From ff7d4e7cc401689b1a2f23ea89e76119134c8f03 Mon Sep 17 00:00:00 2001 From: Sandy Spicer Date: Tue, 1 Oct 2024 15:15:00 -0700 Subject: [PATCH 01/10] funnel udfs python --- docker/clickhouse/user_defined_function.xml | 14 +- .../hogql_queries/insights/funnels/base.py | 41 +- .../funnel_correlation_query_runner.py | 15 +- .../insights/funnels/funnel_udf.py | 182 +- .../insights/funnels/funnels_query_runner.py | 17 +- ...br => test_funnel_correlation_actors.ambr} | 84 +- .../test_funnel_correlation_actors_udf.ambr | 677 + .../test_funnel_correlation_udf.ambr | 5080 +++++++ .../test_funnel_persons_udf.ambr | 220 + .../test_funnel_strict_persons_udf.ambr | 220 + .../__snapshots__/test_funnel_strict_udf.ambr | 1194 +- .../__snapshots__/test_funnel_trends.ambr | 362 - .../__snapshots__/test_funnel_trends_udf.ambr | 30 +- .../test/__snapshots__/test_funnel_udf.ambr | 896 +- .../funnels/test/test_funnel_correlation.py | 16 +- ...s.py => test_funnel_correlation_actors.py} | 10 +- .../test_funnel_correlation_actors_udf.py | 9 + .../test/test_funnel_correlation_udf.py | 9 + .../funnels/test/test_funnel_persons.py | 8 +- .../funnels/test/test_funnel_persons_udf.py | 31 + .../funnels/test/test_funnel_strict.py | 14 +- .../test/test_funnel_strict_persons.py | 8 +- .../test/test_funnel_strict_persons_udf.py | 9 + .../funnels/test/test_funnel_strict_udf.py | 16 +- .../funnels/test/test_funnel_trends.py | 4 +- .../funnels/test/test_funnel_trends_udf.py | 2 +- .../insights/funnels/test/test_funnel_udf.py | 10 +- .../hogql_queries/insights/funnels/utils.py | 21 +- .../test_paths_query_runner_ee.ambr | 11964 +++++++++++++++- .../test/test_paths_query_runner_ee.py | 17 +- .../test/__snapshots__/test_trends.ambr | 204 +- .../user_scripts/test_aggregate_funnel.py | 8423 +++++------ posthog/udf_versioner.py | 2 +- posthog/user_scripts/aggregate_funnel.py | 63 +- posthog/user_scripts/aggregate_funnel_test.py | 3 +- .../latest_user_defined_function.xml | 287 +- 36 files changed, 24670 insertions(+), 5492 deletions(-) rename posthog/hogql_queries/insights/funnels/test/__snapshots__/{test_funnel_correlations_persons.ambr => test_funnel_correlation_actors.ambr} (96%) create mode 100644 posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr create mode 100644 posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr create mode 100644 posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr create mode 100644 posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr rename posthog/hogql_queries/insights/funnels/test/{test_funnel_correlations_persons.py => test_funnel_correlation_actors.py} (98%) create mode 100644 posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors_udf.py create mode 100644 posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_udf.py create mode 100644 posthog/hogql_queries/insights/funnels/test/test_funnel_persons_udf.py create mode 100644 posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons_udf.py diff --git a/docker/clickhouse/user_defined_function.xml b/docker/clickhouse/user_defined_function.xml index 9617d2495ced1..a3175f8e17e48 100644 --- a/docker/clickhouse/user_defined_function.xml +++ b/docker/clickhouse/user_defined_function.xml @@ -2,7 +2,7 @@ executable aggregate_funnel - Array(Tuple(Int8, Nullable(String), Array(Float64))) + Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -25,7 +25,7 @@ prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow @@ -35,7 +35,7 @@ executable aggregate_funnel_cohort - Array(Tuple(Int8, UInt64, Array(Float64))) + Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) result UInt8 @@ -58,7 +58,7 @@ prop_vals - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) value JSONEachRow @@ -68,7 +68,7 @@ executable aggregate_funnel_array - Array(Tuple(Int8, Array(String), Array(Float64))) + Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -91,7 +91,7 @@ prop_vals - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) value JSONEachRow @@ -124,7 +124,7 @@ prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow diff --git a/posthog/hogql_queries/insights/funnels/base.py b/posthog/hogql_queries/insights/funnels/base.py index d5757225246f4..8066ada3c642f 100644 --- a/posthog/hogql_queries/insights/funnels/base.py +++ b/posthog/hogql_queries/insights/funnels/base.py @@ -435,31 +435,26 @@ def _get_inner_event_query_for_udf( extra_fields.append(prop) funnel_events_query = FunnelEventQuery( - context=self.context, - extra_fields=[*self._extra_event_fields, *extra_fields], - extra_event_properties=self._extra_event_properties, + context=self.context, extra_fields=[*self.extra_event_fields_and_properties, *extra_fields] ).to_query( skip_entity_filter=skip_entity_filter, ) - # funnel_events_query, params = FunnelEventQuery( - # extra_fields=[*self._extra_event_fields, *extra_fields], - # extra_event_properties=self._extra_event_properties, - # ).get_query(entities_to_use, entity_name, skip_entity_filter=skip_entity_filter) all_step_cols: list[ast.Expr] = [] all_exclusions: list[list[FunnelExclusionEventsNode | FunnelExclusionActionsNode]] = [] for index, entity in enumerate(entities_to_use): - step_cols = self._get_step_col(entity, index, entity_name) + step_cols = self._get_step_col(entity, index, entity_name, for_udf=True) all_step_cols.extend(step_cols) all_exclusions.append([]) - for excluded_entity in funnelsFilter.exclusions or []: - for i in range(excluded_entity.funnelFromStep + 1, excluded_entity.funnelToStep + 1): - all_exclusions[i].append(excluded_entity) + if funnelsFilter.exclusions: + for excluded_entity in funnelsFilter.exclusions: + for i in range(excluded_entity.funnelFromStep + 1, excluded_entity.funnelToStep + 1): + all_exclusions[i].append(excluded_entity) - for index, exclusions in enumerate(all_exclusions): - exclusion_col_expr = self._get_exclusions_col(exclusions, index, entity_name) - all_step_cols.append(exclusion_col_expr) + for index, exclusions in enumerate(all_exclusions): + exclusion_col_expr = self._get_exclusions_col(exclusions, index, entity_name) + all_step_cols.append(exclusion_col_expr) breakdown_select_prop = self._get_breakdown_select_prop() @@ -491,7 +486,6 @@ def _get_exclusions_col( ) -> ast.Expr: if not exclusions: return parse_expr(f"0 as exclusion_{index}") - conditions = [self._build_step_query(exclusion, index, entity_name, "") for exclusion in exclusions] return parse_expr( f"if({{condition}}, 1, 0) as exclusion_{index}", placeholders={"condition": ast.Or(exprs=conditions)} @@ -664,10 +658,10 @@ def _get_step_col( parse_expr(f"if({step_prefix}step_{index} = 1, timestamp, null) as {step_prefix}latest_{index}") ) - for field in self.extra_event_fields_and_properties: - step_cols.append( - parse_expr(f'if({step_prefix}step_{index} = 1, "{field}", null) as "{step_prefix}{field}_{index}"') - ) + for field in self.extra_event_fields_and_properties: + step_cols.append( + parse_expr(f'if({step_prefix}step_{index} = 1, "{field}", null) as "{step_prefix}{field}_{index}"') + ) return step_cols @@ -758,12 +752,15 @@ def _get_funnel_person_step_condition(self) -> ast.Expr: return ast.And(exprs=conditions) - def _get_funnel_person_step_events(self) -> list[ast.Expr]: - if ( + def _include_matched_events(self): + return ( hasattr(self.context, "actorsQuery") and self.context.actorsQuery is not None and self.context.actorsQuery.includeRecordings - ): + ) + + def _get_funnel_person_step_events(self) -> list[ast.Expr]: + if self._include_matched_events(): if self.context.includeFinalMatchingEvents: # Always returns the user's final step of the funnel return [parse_expr("final_matching_events as matching_events")] diff --git a/posthog/hogql_queries/insights/funnels/funnel_correlation_query_runner.py b/posthog/hogql_queries/insights/funnels/funnel_correlation_query_runner.py index e37ee95ce6b48..e67e00d9d04a1 100644 --- a/posthog/hogql_queries/insights/funnels/funnel_correlation_query_runner.py +++ b/posthog/hogql_queries/insights/funnels/funnel_correlation_query_runner.py @@ -4,6 +4,7 @@ from posthog.constants import AUTOCAPTURE_EVENT from posthog.hogql.parser import parse_select from posthog.hogql.property import property_to_expr +from posthog.hogql_queries.insights.funnels import FunnelUDF from posthog.hogql_queries.insights.funnels.funnel_event_query import FunnelEventQuery from posthog.hogql_queries.insights.funnels.funnel_persons import FunnelActors from posthog.hogql_queries.insights.funnels.funnel_strict_persons import FunnelStrictActors @@ -19,7 +20,11 @@ from posthog.hogql.query import execute_hogql_query from posthog.hogql.timings import HogQLTimings from posthog.hogql_queries.insights.funnels.funnel_query_context import FunnelQueryContext -from posthog.hogql_queries.insights.funnels.utils import funnel_window_interval_unit_to_sql, get_funnel_actor_class +from posthog.hogql_queries.insights.funnels.utils import ( + funnel_window_interval_unit_to_sql, + get_funnel_actor_class, + use_udf, +) from posthog.hogql_queries.query_runner import QueryRunner from posthog.models import Team from posthog.models.property.util import get_property_string_expr @@ -93,7 +98,7 @@ class FunnelCorrelationQueryRunner(QueryRunner): actors_query: FunnelsActorsQuery correlation_actors_query: Optional[FunnelCorrelationActorsQuery] - _funnel_actors_generator: FunnelActors | FunnelStrictActors | FunnelUnorderedActors + _funnel_actors_generator: FunnelActors | FunnelStrictActors | FunnelUnorderedActors | FunnelUDF def __init__( self, @@ -132,9 +137,11 @@ def __init__( self.context.actorsQuery = self.actors_query # Used for generating the funnel persons cte - funnel_order_actor_class = get_funnel_actor_class(self.context.funnelsFilter)(context=self.context) + funnel_order_actor_class = get_funnel_actor_class( + self.context.funnelsFilter, use_udf(self.context.funnelsFilter, self.team) + )(context=self.context) assert isinstance( - funnel_order_actor_class, FunnelActors | FunnelStrictActors | FunnelUnorderedActors + funnel_order_actor_class, FunnelActors | FunnelStrictActors | FunnelUnorderedActors | FunnelUDF ) # for typings self._funnel_actors_generator = funnel_order_actor_class diff --git a/posthog/hogql_queries/insights/funnels/funnel_udf.py b/posthog/hogql_queries/insights/funnels/funnel_udf.py index 7ec91374dcdee..b2568acc74538 100644 --- a/posthog/hogql_queries/insights/funnels/funnel_udf.py +++ b/posthog/hogql_queries/insights/funnels/funnel_udf.py @@ -1,7 +1,7 @@ -from typing import cast +from typing import cast, Optional from posthog.hogql import ast -from posthog.hogql.parser import parse_select +from posthog.hogql.parser import parse_select, parse_expr from posthog.hogql_queries.insights.funnels.base import FunnelBase from posthog.schema import BreakdownType, BreakdownAttributionType from posthog.utils import DATERANGE_MAP @@ -11,6 +11,16 @@ class FunnelUDF(FunnelBase): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # In base, these fields only get added if you're running an actors query + if "uuid" not in self._extra_event_fields: + self._extra_event_fields.append("uuid") + for property in ("$session_id", "$window_id"): + if property not in self._extra_event_properties: + self._extra_event_properties.append(property) + + # I think I can delete this def get_step_counts_query(self): max_steps = self.context.max_steps return self._get_step_counts_query( @@ -27,7 +37,9 @@ def conversion_window_limit(self) -> int: self.context.funnelWindowInterval * DATERANGE_MAP[self.context.funnelWindowIntervalUnit].total_seconds() ) - def get_query(self) -> ast.SelectQuery: + # This is the function that calls the UDF + # This is used by both the query itself and the actors query + def _inner_aggregation_query(self): if self.context.funnelsFilter.funnelOrderType == "strict": inner_event_query = self._get_inner_event_query_for_udf( entity_name="events", skip_step_filter=True, skip_entity_filter=True @@ -63,30 +75,20 @@ def get_query(self) -> ast.SelectQuery: breakdown_attribution_string = f"{self.context.breakdownAttributionType}{f'_{self.context.funnelsFilter.breakdownAttributionValue}' if self.context.breakdownAttributionType == BreakdownAttributionType.STEP else ''}" - # test - ''' - inner_select = parse_select( - f""" - SELECT - arrayJoin({fn}( - {self.context.max_steps}, - {self.conversion_window_limit()}, - '{breakdown_attribution_string}', - '{self.context.funnelsFilter.funnelOrderType}', - {prop_vals}, - arraySort(t -> t.1, groupArray(tuple(toFloat(timestamp), {prop_selector}, arrayFilter((x) -> x != 0, [{steps}{exclusions}])))) - )) as af_tuple, - af_tuple.1 as af, - af_tuple.2 as breakdown, - af_tuple.3 as timings - FROM {{inner_event_query}} - GROUP BY aggregation_target{breakdown_prop} - HAVING af >= 0 - """, - {"inner_event_query": inner_event_query}, - ) - return inner_select - ''' + def matched_event_arrays_selects(): + # We use matched events to get timestamps for the funnel as well as recordings + if ( + self._include_matched_events() + or self.context.includePrecedingTimestamp + or self.context.includeTimestamp + ): + return """ + af_tuple.4 as matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, $session_id, $window_id)) as user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) as user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) as matched_events_array, + """ + return "" inner_select = parse_select( f""" @@ -97,20 +99,27 @@ def get_query(self) -> ast.SelectQuery: '{breakdown_attribution_string}', '{self.context.funnelsFilter.funnelOrderType}', {prop_vals}, - arraySort(t -> t.1, groupArray(tuple(toFloat(timestamp), {prop_selector}, arrayFilter((x) -> x != 0, [{steps}{exclusions}])))) + arraySort(t -> t.1, groupArray(tuple(toFloat(timestamp), uuid, {prop_selector}, arrayFilter((x) -> x != 0, [{steps}{exclusions}])))) )) as af_tuple, - af_tuple.1 as af, + af_tuple.1 as step_reached, + af_tuple.1 + 1 as steps, -- Backward compatibility af_tuple.2 as breakdown, - af_tuple.3 as timings + af_tuple.3 as timings, + {matched_event_arrays_selects()} + aggregation_target FROM {{inner_event_query}} GROUP BY aggregation_target{breakdown_prop} - HAVING af >= 0 + HAVING step_reached >= 0 """, {"inner_event_query": inner_event_query}, ) + return inner_select + + def get_query(self) -> ast.SelectQuery: + inner_select = self._inner_aggregation_query() step_results = ",".join( - [f"countIf(ifNull(equals(af, {i}), 0)) AS step_{i+1}" for i in range(self.context.max_steps)] + [f"countIf(ifNull(equals(step_reached, {i}), 0)) AS step_{i+1}" for i in range(self.context.max_steps)] ) step_results2 = ",".join([f"sum(step_{i+1}) AS step_{i+1}" for i in range(self.context.max_steps)]) @@ -182,3 +191,112 @@ def get_query(self) -> ast.SelectQuery: ) return cast(ast.SelectQuery, s) + + def _get_funnel_person_step_condition(self) -> ast.Expr: + actorsQuery, breakdownType = ( + self.context.actorsQuery, + self.context.breakdownType, + ) + assert actorsQuery is not None + + funnelStep = actorsQuery.funnelStep + funnelCustomSteps = actorsQuery.funnelCustomSteps + funnelStepBreakdown = actorsQuery.funnelStepBreakdown + + conditions: list[ast.Expr] = [] + + if funnelCustomSteps: + # this is an adjustment for how UDF funnels represent steps + funnelCustomSteps = [x - 1 for x in funnelCustomSteps] + conditions.append(parse_expr(f"step_reached IN {funnelCustomSteps}")) + elif funnelStep is not None: + if funnelStep >= 0: + conditions.append(parse_expr(f"step_reached >= {funnelStep - 1}")) + else: + conditions.append(parse_expr(f"step_reached = {-funnelStep - 2}")) + else: + raise ValueError("Missing both funnelStep and funnelCustomSteps") + + if funnelStepBreakdown is not None: + if isinstance(funnelStepBreakdown, int) and breakdownType != "cohort": + funnelStepBreakdown = str(funnelStepBreakdown) + + conditions.append( + parse_expr( + "arrayFlatten(array(breakdown)) = arrayFlatten(array({funnelStepBreakdown}))", + {"funnelStepBreakdown": ast.Constant(value=funnelStepBreakdown)}, + ) + ) + + return ast.And(exprs=conditions) + + def _get_funnel_person_step_events(self) -> list[ast.Expr]: + if ( + hasattr(self.context, "actorsQuery") + and self.context.actorsQuery is not None + and self.context.actorsQuery.includeRecordings + ): + if self.context.includeFinalMatchingEvents: + # Always returns the user's final step of the funnel, 1 indexed + return [parse_expr("matched_events_array[step_reached + 1] as matching_events")] + + absolute_actors_step = self._absolute_actors_step + if absolute_actors_step is None: + raise ValueError("Missing funnelStep actors query property") + return [parse_expr(f"matched_events_array[{absolute_actors_step + 1}] as matching_events")] + return [] + + def _get_timestamp_outer_select(self) -> list[ast.Expr]: + """ + Returns timestamp selectors for the target step and optionally the preceding step. + In the former case, always returns the timestamp for the first and last step as well. + """ + target_step = self._absolute_actors_step + + if target_step is None: + return [] + + # We pull timestamps from matched_events_array and SQL arrays are 1-indexed + target_step += 1 + + final_step = self.context.max_steps + first_step = 1 + + if self.context.includePrecedingTimestamp: + if target_step == 0: + raise ValueError("Cannot request preceding step timestamp if target funnel step is the first step") + + return [ + parse_expr(f"matched_events_array[{target_step}][1].1 AS max_timestamp"), + parse_expr(f"matched_events_array[{target_step - 1}][1].1 AS min_timestamp"), + ] + elif self.context.includeTimestamp: + return [ + parse_expr(f"matched_events_array[{target_step}][1].1 AS timestamp"), + # Correlation code expects null if user hasn't made it to this step + parse_expr(f"nullIf(matched_events_array[{final_step}][1].1, 0) AS final_timestamp"), + parse_expr(f"matched_events_array[{first_step}][1].1 as first_timestamp"), + ] + else: + return [] + + def actor_query( + self, + extra_fields: Optional[list[str]] = None, + ) -> ast.SelectQuery: + select: list[ast.Expr] = [ + ast.Alias(alias="actor_id", expr=ast.Field(chain=["aggregation_target"])), + *self._get_funnel_person_step_events(), + *self._get_timestamp_outer_select(), + *([ast.Field(chain=[field]) for field in extra_fields or []]), + ] + select_from = ast.JoinExpr(table=self._inner_aggregation_query()) + where = self._get_funnel_person_step_condition() + order_by = [ast.OrderExpr(expr=ast.Field(chain=["aggregation_target"]))] + + return ast.SelectQuery( + select=select, + select_from=select_from, + order_by=order_by, + where=where, + ) diff --git a/posthog/hogql_queries/insights/funnels/funnels_query_runner.py b/posthog/hogql_queries/insights/funnels/funnels_query_runner.py index dcd5056d70bfa..0e8a7919a76ec 100644 --- a/posthog/hogql_queries/insights/funnels/funnels_query_runner.py +++ b/posthog/hogql_queries/insights/funnels/funnels_query_runner.py @@ -19,11 +19,7 @@ from posthog.hogql_queries.insights.funnels.funnel_time_to_convert import FunnelTimeToConvert from posthog.hogql_queries.insights.funnels.funnel_trends import FunnelTrends from posthog.hogql_queries.insights.funnels.funnel_trends_udf import FunnelTrendsUDF -from posthog.hogql_queries.insights.funnels.utils import get_funnel_actor_class, get_funnel_order_class -from posthog.hogql_queries.legacy_compatibility.feature_flag import ( - insight_funnels_use_udf, - insight_funnels_use_udf_trends, -) +from posthog.hogql_queries.insights.funnels.utils import get_funnel_actor_class, get_funnel_order_class, use_udf from posthog.hogql_queries.query_runner import QueryRunner from posthog.hogql_queries.utils.query_date_range import QueryDateRange from posthog.models import Team @@ -115,14 +111,7 @@ def calculate(self): @cached_property def _use_udf(self): - if self.context.funnelsFilter.useUdf: - return True - funnelVizType = self.context.funnelsFilter.funnelVizType - if funnelVizType == FunnelVizType.TRENDS and insight_funnels_use_udf_trends(self.team): - return True - if funnelVizType == FunnelVizType.STEPS and insight_funnels_use_udf(self.team): - return True - return False + return use_udf(self.context.funnelsFilter, self.team) @cached_property def funnel_order_class(self): @@ -145,7 +134,7 @@ def funnel_class(self): @cached_property def funnel_actor_class(self): - return get_funnel_actor_class(self.context.funnelsFilter)(context=self.context) + return get_funnel_actor_class(self.context.funnelsFilter, self._use_udf)(context=self.context) @cached_property def query_date_range(self): diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlations_persons.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors.ambr similarity index 96% rename from posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlations_persons.ambr rename to posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors.ambr index 7577455686ab6..fc9dcbeb30399 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlations_persons.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: TestFunnelCorrelationsActors.test_funnel_correlation_on_event_with_recordings +# name: TestFunnelCorrelationActors.test_funnel_correlation_on_event_with_recordings ''' SELECT persons.id, persons.id AS id, @@ -172,7 +172,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_funnel_correlation_on_event_with_recordings.1 +# name: TestFunnelCorrelationActors.test_funnel_correlation_on_event_with_recordings.1 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -186,7 +186,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_funnel_correlation_on_event_with_recordings.2 +# name: TestFunnelCorrelationActors.test_funnel_correlation_on_event_with_recordings.2 ''' SELECT persons.id, persons.id AS id, @@ -437,7 +437,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_funnel_correlation_on_event_with_recordings.3 +# name: TestFunnelCorrelationActors.test_funnel_correlation_on_event_with_recordings.3 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -451,7 +451,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_funnel_correlation_on_properties_with_recordings +# name: TestFunnelCorrelationActors.test_funnel_correlation_on_properties_with_recordings ''' SELECT persons.id, persons.id AS id, @@ -628,7 +628,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_funnel_correlation_on_properties_with_recordings.1 +# name: TestFunnelCorrelationActors.test_funnel_correlation_on_properties_with_recordings.1 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -642,7 +642,71 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_strict_funnel_correlation_with_recordings +# name: TestFunnelCorrelationActors.test_strict_funnel_correlation_with_recordings + ''' + SELECT countIf(ifNull(equals(steps, 1), 0)) AS step_1, + countIf(ifNull(equals(steps, 2), 0)) AS step_2, + avg(step_1_average_conversion_time_inner) AS step_1_average_conversion_time, + median(step_1_median_conversion_time_inner) AS step_1_median_conversion_time + FROM + (SELECT aggregation_target AS aggregation_target, + steps AS steps, + avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, + median(step_1_conversion_time) AS step_1_median_conversion_time_inner + FROM + (SELECT aggregation_target AS aggregation_target, + steps AS steps, + max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, + step_1_conversion_time AS step_1_conversion_time + FROM + (SELECT aggregation_target AS aggregation_target, + timestamp AS timestamp, + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1) AS steps, + if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time + FROM + (SELECT aggregation_target AS aggregation_target, + timestamp AS timestamp, + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + min(latest_1) OVER (PARTITION BY aggregation_target + ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) AS latest_1 + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC')))))) + WHERE ifNull(equals(step_0, 1), 0))) + GROUP BY aggregation_target, + steps + HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) + and isNull(max(max_steps)))) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelCorrelationActors.test_strict_funnel_correlation_with_recordings.1 ''' SELECT persons.id, persons.id AS id, @@ -819,7 +883,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_strict_funnel_correlation_with_recordings.1 +# name: TestFunnelCorrelationActors.test_strict_funnel_correlation_with_recordings.2 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -833,7 +897,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_strict_funnel_correlation_with_recordings.2 +# name: TestFunnelCorrelationActors.test_strict_funnel_correlation_with_recordings.3 ''' SELECT persons.id, persons.id AS id, @@ -1010,7 +1074,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestFunnelCorrelationsActors.test_strict_funnel_correlation_with_recordings.3 +# name: TestFunnelCorrelationActors.test_strict_funnel_correlation_with_recordings.4 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr new file mode 100644 index 0000000000000..0162d9d172265 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr @@ -0,0 +1,677 @@ +# serializer version: 1 +# name: TestFunnelCorrelationsActorsUDF.test_funnel_correlation_on_event_with_recordings + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS event__override ON equals(event.distinct_id, event__override.distinct_id) + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'insight analyzed'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(if(not(empty(event__override.distinct_id)), event__override.person_id, event.person_id), funnel_actors.actor_id) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC')))), notIn(event.event, ['$pageview', 'insight analyzed']), equals(event.event, 'insight loaded'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM events AS event + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS event__override ON equals(event.distinct_id, event__override.distinct_id) + JOIN + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'insight analyzed'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(if(not(empty(event__override.distinct_id)), event__override.person_id, event.person_id), funnel_actors.actor_id) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC')))), notIn(event.event, ['$pageview', 'insight analyzed']), equals(event.event, 'insight loaded'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_funnel_correlation_on_event_with_recordings.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_funnel_correlation_on_event_with_recordings.2 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS event__override ON equals(event.distinct_id, event__override.distinct_id) + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[3][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1, + if(equals(e.event, 'insight updated'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'insight analyzed', 'insight updated'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(if(not(empty(event__override.distinct_id)), event__override.person_id, event.person_id), funnel_actors.actor_id) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC')))), notIn(event.event, ['$pageview', 'insight analyzed', 'insight updated']), equals(event.event, 'insight loaded'), ifNull(notEquals(funnel_actors.steps, 3), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM events AS event + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS event__override ON equals(event.distinct_id, event__override.distinct_id) + JOIN + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[3][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1, if(equals(e.event, 'insight updated'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'insight analyzed', 'insight updated'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(if(not(empty(event__override.distinct_id)), event__override.person_id, event.person_id), funnel_actors.actor_id) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2021-01-08 23:59:59', 6, 'UTC')))), notIn(event.event, ['$pageview', 'insight analyzed', 'insight updated']), equals(event.event, 'insight loaded'), ifNull(notEquals(funnel_actors.steps, 3), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_funnel_correlation_on_event_with_recordings.3 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_funnel_correlation_on_properties_with_recordings + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'foo'), ''), 'null'), '^"|"$', '') AS properties___foo + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'insight analyzed')), ifNull(equals(e__person.properties___foo, 'bar'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'foo'), ''), 'null'), '^"|"$', '') AS properties___foo + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'insight analyzed')), ifNull(equals(e__person.properties___foo, 'bar'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_funnel_correlation_on_properties_with_recordings.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_strict_funnel_correlation_with_recordings + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + rowNumberInBlock() AS row_number, + breakdown AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_strict_funnel_correlation_with_recordings.1 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'foo'), ''), 'null'), '^"|"$', '') AS properties___foo + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), ifNull(equals(e__person.properties___foo, 'bar'), 0))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'foo'), ''), 'null'), '^"|"$', '') AS properties___foo + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), ifNull(equals(e__person.properties___foo, 'bar'), 0))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_strict_funnel_correlation_with_recordings.2 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_strict_funnel_correlation_with_recordings.3 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, '$pageview'), 1, 0) AS step_0, + if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'foo'), ''), 'null'), '^"|"$', '') AS properties___foo + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), ifNull(equals(e__person.properties___foo, 'bar'), 0))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'foo'), ''), 'null'), '^"|"$', '') AS properties___foo + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), ifNull(equals(e__person.properties___foo, 'bar'), 0))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelCorrelationsActorsUDF.test_strict_funnel_correlation_with_recordings.4 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s3'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr new file mode 100644 index 0000000000000..5dd4947101474 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr @@ -0,0 +1,5080 @@ +# serializer version: 1 +# name: TestClickhouseFunnelCorrelationUDF.test_action_events_are_excluded_from_correlations + ''' + SELECT event.event AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM events AS event + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS event__override ON equals(event.distinct_id, event__override.distinct_id) + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(and(equals(e.event, 'user signed up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), 1, 0) AS step_0, + if(and(equals(e.event, 'paid'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(if(not(empty(event__override.distinct_id)), event__override.person_id, event.person_id), funnel_actors.actor_id) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), notIn(event.event, [])) + GROUP BY name + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(and(equals(e.event, 'user signed up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), 1, 0) AS step_0, + if(and(equals(e.event, 'paid'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['$browser'], [JSONExtractString(persons.person_props, '$browser')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + JOIN + (SELECT persons.id AS id, + persons.properties AS person_props + FROM + (SELECT person.id AS id, + person.properties AS properties + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons) AS persons ON equals(persons.id, funnel_actors.actor_id)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.1 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.2 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.3 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.4 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.5 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.6 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.7 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties.8 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['$browser'], [JSONExtractString(persons.person_props, '$browser')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + JOIN + (SELECT persons.id AS id, + persons.properties AS person_props + FROM + (SELECT person.id AS id, + person.properties AS properties + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons) AS persons ON equals(persons.id, funnel_actors.actor_id)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.1 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.2 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.3 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.4 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.5 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.6 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.7 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, nullIf(nullIf(person.`pmat_$browser`, ''), 'null') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__person.`properties___$browser`, 'Negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_basic_funnel_correlation_with_properties_materialized.8 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2019-12-31 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_event_properties_and_groups + ''' + SELECT concat(ifNull(toString(event_name), ''), '::', ifNull(toString((prop).1), ''), '::', ifNull(toString((prop).2), '')) AS name, + countDistinctIf(actor_id, ifNull(equals(steps, 2), 0)) AS success_count, + countDistinctIf(actor_id, ifNull(notEquals(steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + event.event AS event_name, + arrayJoin(JSONExtractKeysAndValues(event.properties, 'String')) AS prop + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_1` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_1`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), in(event.event, ['positively_related', 'negatively_related']))) + GROUP BY name + HAVING and(ifNull(greater(plus(success_count, failure_count), 2), 0), ifNull(notIn((prop).1, []), 0)) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_1` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_event_properties_and_groups_materialized + ''' + SELECT concat(ifNull(toString(event_name), ''), '::', ifNull(toString((prop).1), ''), '::', ifNull(toString((prop).2), '')) AS name, + countDistinctIf(actor_id, ifNull(equals(steps, 2), 0)) AS success_count, + countDistinctIf(actor_id, ifNull(notEquals(steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + event.event AS event_name, + arrayJoin(JSONExtractKeysAndValues(event.properties, 'String')) AS prop + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_1` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_1`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), in(event.event, ['positively_related', 'negatively_related']))) + GROUP BY name + HAVING and(ifNull(greater(plus(success_count, failure_count), 2), 0), ifNull(notIn((prop).1, []), 0)) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_1` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups + ''' + SELECT event.event AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), notIn(event.event, [])) + GROUP BY name + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'positively_related'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'positively_related'), ifNull(notEquals(funnel_actors.steps, 2), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(notEquals(funnel_actors.steps, 2), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.5 + ''' + SELECT event.event AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'finance'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), notIn(event.event, [])) + GROUP BY name + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'finance'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.6 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups.7 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(notEquals(funnel_actors.steps, 2), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2 + ''' + SELECT event.event AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), notIn(event.event, [])) + GROUP BY name + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'positively_related'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'positively_related'), ifNull(notEquals(funnel_actors.steps, 2), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(notEquals(funnel_actors.steps, 2), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.5 + ''' + SELECT event.event AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'finance'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), notIn(event.event, [])) + GROUP BY name + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'finance'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.6 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(equals(funnel_actors.steps, 2), 0)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_events_and_groups_poe_v2.7 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM events AS event + JOIN + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors ON equals(funnel_actors.actor_id, event.`$group_0`) + WHERE and(equals(event.team_id, 2), greaterOrEquals(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC'))), equals(event.team_id, 2), greater(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), funnel_actors.first_timestamp), less(toTimeZone(toDateTime(toTimeZone(event.timestamp, 'UTC'), 'UTC'), 'UTC'), coalesce(funnel_actors.final_timestamp, plus(toTimeZone(funnel_actors.first_timestamp, 'UTC'), toIntervalDay(14)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-14 23:59:59', 6, 'UTC')))), notIn(event.event, ['paid', 'user signed up']), equals(event.event, 'negatively_related'), ifNull(notEquals(funnel_actors.steps, 2), 1)) + GROUP BY actor_id + ORDER BY actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['industry'], [JSONExtractString(groups_0.properties, 'industry')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups.5 + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(JSONExtractKeysAndValues(groups_0.properties, 'String')) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_materialized + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['industry'], [JSONExtractString(groups_0.properties, 'industry')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_materialized.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_materialized.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_materialized.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_materialized.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_materialized.5 + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(JSONExtractKeysAndValues(groups_0.properties, 'String')) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['industry'], [JSONExtractString(groups_0.properties, 'industry')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events.5 + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(JSONExtractKeysAndValues(groups_0.properties, 'String')) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_materialized + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['industry'], [JSONExtractString(groups_0.properties, 'industry')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_materialized.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_materialized.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_materialized.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_materialized.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_materialized.5 + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(JSONExtractKeysAndValues(groups_0.properties, 'String')) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_poe_v2 + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(arrayZip(['industry'], [JSONExtractString(groups_0.properties, 'industry')])) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_poe_v2.1 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_poe_v2.2 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'positive'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_poe_v2.3 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(equals(funnel_actors.steps, 2), 0) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_poe_v2.4 + ''' + SELECT source.actor_id AS actor_id + FROM + (SELECT funnel_actors.actor_id AS actor_id, + any(funnel_actors.matching_events) AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[plus(step_reached, 1)] AS matching_events, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up')), ifNull(equals(e__group_0.properties___industry, 'negative'), 0)), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + WHERE ifNull(notEquals(funnel_actors.steps, 2), 1) + GROUP BY funnel_actors.actor_id + ORDER BY funnel_actors.actor_id ASC) AS source + INNER JOIN + (SELECT groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups ON equals(groups.key, source.actor_id) + ORDER BY source.actor_id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhouseFunnelCorrelationUDF.test_funnel_correlation_with_properties_and_groups_person_on_events_poe_v2.5 + ''' + SELECT concat(ifNull(toString((aggregation_target_with_props.prop).1), ''), '::', ifNull(toString((aggregation_target_with_props.prop).2), '')) AS name, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(equals(aggregation_target_with_props.steps, 2), 0)) AS success_count, + countDistinctIf(aggregation_target_with_props.actor_id, ifNull(notEquals(aggregation_target_with_props.steps, 2), 1)) AS failure_count + FROM + (SELECT funnel_actors.actor_id AS actor_id, + funnel_actors.steps AS steps, + arrayJoin(JSONExtractKeysAndValues(groups_0.properties, 'String')) AS prop + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LEFT JOIN + (SELECT groups.key AS key, + groups.properties AS properties + FROM + (SELECT argMax(groups.group_properties, toTimeZone(groups._timestamp, 'UTC')) AS properties, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE equals(groups.team_id, 2) + GROUP BY groups.group_type_index, + groups.group_key) AS groups + WHERE ifNull(equals(groups.index, 0), 0)) AS groups_0 ON equals(funnel_actors.actor_id, groups_0.key)) AS aggregation_target_with_props + GROUP BY (aggregation_target_with_props.prop).1, (aggregation_target_with_props.prop).2 + HAVING ifNull(notIn((aggregation_target_with_props.prop).1, []), 0) + LIMIT 100 + UNION ALL + SELECT 'Total_Values_In_Query' AS name, + countDistinctIf(funnel_actors.actor_id, ifNull(equals(funnel_actors.steps, 2), 0)) AS success_count, + countDistinctIf(funnel_actors.actor_id, ifNull(notEquals(funnel_actors.steps, 2), 1)) AS failure_count + FROM + (SELECT aggregation_target AS actor_id, + (matched_events_array[1][1]).1 AS timestamp, + nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, + (matched_events_array[1][1]).1 AS first_timestamp, + steps AS steps, + final_timestamp, + first_timestamp + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(equals(e.event, 'paid'), 1, 0) AS step_1 + FROM events AS e + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS funnel_actors + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr new file mode 100644 index 0000000000000..53ead043ec8e9 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr @@ -0,0 +1,220 @@ +# serializer version: 1 +# name: TestFunnelPersonsUDF.test_funnel_person_recordings + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[1] AS matching_events + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelPersonsUDF.test_funnel_person_recordings.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s1'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelPersonsUDF.test_funnel_person_recordings.2 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[2] AS matching_events + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 1), 0) + ORDER BY aggregation_target ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelPersonsUDF.test_funnel_person_recordings.3 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelPersonsUDF.test_funnel_person_recordings.4 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[2] AS matching_events + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(equals(step_reached, 1), 0) + ORDER BY aggregation_target ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelPersonsUDF.test_funnel_person_recordings.5 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr new file mode 100644 index 0000000000000..91c999226376f --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr @@ -0,0 +1,220 @@ +# serializer version: 1 +# name: TestFunnelStrictStepsPersons.test_strict_funnel_person_recordings + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[1] AS matching_events + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) + ORDER BY aggregation_target ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelStrictStepsPersons.test_strict_funnel_person_recordings.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s1'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelStrictStepsPersons.test_strict_funnel_person_recordings.2 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[2] AS matching_events + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 1), 0) + ORDER BY aggregation_target ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelStrictStepsPersons.test_strict_funnel_person_recordings.3 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestFunnelStrictStepsPersons.test_strict_funnel_person_recordings.4 + ''' + SELECT persons.id, + persons.id AS id, + source.matching_events AS matching_events + FROM + (SELECT aggregation_target AS actor_id, + matched_events_array[2] AS matching_events + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + af_tuple.4 AS matched_event_uuids_array_array, + groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, + mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, + arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, + aggregation_target AS aggregation_target + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-01-08 23:59:59.999999', 6, 'UTC'))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(equals(step_reached, 1), 0) + ORDER BY aggregation_target ASC) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelStrictStepsPersons.test_strict_funnel_person_recordings.5 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2021-01-02 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s2'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr index 66b5642a0d5f4..4bd394de540b2 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr @@ -1135,38 +1135,38 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1180,7 +1180,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1203,40 +1203,40 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - prop_basic AS prop_basic, - prop_0 AS prop_0, - prop_1 AS prop_1, - prop, - prop_vals AS prop_vals, - prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop_0 AS prop_0, + prop_1 AS prop_1, + prop, + prop_vals AS prop_vals, + prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, if(ifNull(equals(step_0, 1), 0), prop_basic, []) AS prop_0, if(ifNull(equals(step_1, 1), 0), prop_basic, []) AS prop_1, @@ -1255,7 +1255,7 @@ WHERE ifNull(notEquals(prop, []), isNotNull(prop) or isNotNull([]))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1278,38 +1278,38 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'buy'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), ''), ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1323,7 +1323,218 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelStrictStepsBreakdownUDF.test_funnel_breakdown_correct_breakdown_props_are_chosen + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + rowNumberInBlock() AS row_number, + if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT timestamp AS timestamp, + aggregation_target AS aggregation_target, + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, + [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, + prop_basic AS prop, + argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelStrictStepsBreakdownUDF.test_funnel_breakdown_correct_breakdown_props_are_chosen_for_step + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + rowNumberInBlock() AS row_number, + if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT timestamp AS timestamp, + aggregation_target AS aggregation_target, + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop_0 AS prop_0, + prop_1 AS prop_1, + prop, + prop_vals AS prop_vals, + prop + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, + [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, + if(ifNull(equals(step_0, 1), 0), prop_basic, []) AS prop_0, + if(ifNull(equals(step_1, 1), 0), prop_basic, []) AS prop_1, + prop_1 AS prop, + groupUniqArray(prop) OVER (PARTITION BY aggregation_target) AS prop_vals + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC'))))) ARRAY + JOIN prop_vals AS prop + WHERE ifNull(notEquals(prop, []), isNotNull(prop) + or isNotNull([]))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestFunnelStrictStepsBreakdownUDF.test_funnel_step_multiple_breakdown_snapshot + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + rowNumberInBlock() AS row_number, + if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT timestamp AS timestamp, + aggregation_target AS aggregation_target, + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(equals(e.event, 'buy'), 1, 0) AS step_1, + [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), ''), ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, + prop_basic AS prop, + argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1349,46 +1560,42 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - exclusion_2 AS exclusion_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1403,7 +1610,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1429,46 +1636,42 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - exclusion_2 AS exclusion_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1483,7 +1686,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1509,46 +1712,42 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - exclusion_2 AS exclusion_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1570,7 +1769,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -2064,3 +2263,718 @@ max_expanded_ast_elements=1000000 ''' # --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_aggregate_by_groups_breakdown_group_person_on_events + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + sum(step_3) AS step_3, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_2_conversion_times)])[1] AS step_2_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_2_conversion_times)])[1] AS step_2_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, + rowNumberInBlock() AS row_number, + if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT timestamp AS timestamp, + aggregation_target AS aggregation_target, + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(equals(e.event, 'play movie'), 1, 0) AS step_1, + if(equals(e.event, 'buy'), 1, 0) AS step_2, + ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, + prop_basic AS prop, + argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_aggregate_by_groups_breakdown_group_person_on_events_poe_v2 + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + sum(step_3) AS step_3, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_2_conversion_times)])[1] AS step_2_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_2_conversion_times)])[1] AS step_2_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, + rowNumberInBlock() AS row_number, + if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT timestamp AS timestamp, + aggregation_target AS aggregation_target, + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(equals(e.event, 'play movie'), 1, 0) AS step_1, + if(equals(e.event, 'buy'), 1, 0) AS step_2, + ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, + prop_basic AS prop, + argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals + FROM events AS e + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group + ''' + SELECT sum(step_1) AS step_1, + sum(step_2) AS step_2, + sum(step_3) AS step_3, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_1_conversion_times)])[1] AS step_1_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [avgArrayOrNull(step_2_conversion_times)])[1] AS step_2_average_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_1_conversion_times)])[1] AS step_1_median_conversion_time, + arrayMap(x -> if(isNaN(x), NULL, x), [medianArrayOrNull(step_2_conversion_times)])[1] AS step_2_median_conversion_time, + groupArray(row_number) AS row_number, + final_prop AS final_prop + FROM + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, + groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, + groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, + rowNumberInBlock() AS row_number, + if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop + FROM + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target + FROM + (SELECT timestamp AS timestamp, + aggregation_target AS aggregation_target, + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop + FROM + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(equals(e.event, 'play movie'), 1, 0) AS step_1, + if(equals(e.event, 'buy'), 1, 0) AS step_2, + ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, + prop_basic AS prop, + argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) + WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + GROUP BY breakdown + ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) + GROUP BY final_prop + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128, + allow_experimental_analyzer=1 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.1 + ''' + + SELECT replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS value, + count(*) as count + FROM events e + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND event IN ['buy', 'play movie', 'sign up'] + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + GROUP BY value + ORDER BY count DESC, value DESC + LIMIT 26 + OFFSET 0 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.2 + ''' + + SELECT aggregation_target AS actor_id + FROM + (SELECT aggregation_target, + steps, + avg(step_1_conversion_time) step_1_average_conversion_time_inner, + avg(step_2_conversion_time) step_2_average_conversion_time_inner, + median(step_1_conversion_time) step_1_median_conversion_time_inner, + median(step_2_conversion_time) step_2_median_conversion_time_inner, + prop + FROM + (SELECT aggregation_target, + steps, + max(steps) over (PARTITION BY aggregation_target, + prop) as max_steps, + step_1_conversion_time, + step_2_conversion_time, + prop + FROM + (SELECT *, + if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY + AND latest_1 <= latest_2 + AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps, + if(isNotNull(latest_1) + AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, + if(isNotNull(latest_2) + AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time + FROM + (SELECT aggregation_target, timestamp, step_0, + latest_0, + step_1, + min(latest_1) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) latest_1, + step_2, + min(latest_2) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) latest_2 , + if(has(['technology', 'finance'], prop), prop, 'Other') as prop + FROM + (SELECT *, + prop_vals as prop + FROM + (SELECT e.timestamp as timestamp, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as aggregation_target, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as person_id, + if(event = 'sign up', 1, 0) as step_0, + if(step_0 = 1, timestamp, null) as latest_0, + if(event = 'play movie', 1, 0) as step_1, + if(step_1 = 1, timestamp, null) as latest_1, + if(event = 'buy', 1, 0) as step_2, + if(step_2 = 1, timestamp, null) as latest_2, + replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS prop_basic, + prop_basic as prop, + argMinIf(prop, timestamp, isNotNull(prop)) over (PARTITION by aggregation_target) as prop_vals + FROM events e + LEFT OUTER JOIN + (SELECT distinct_id, + argMax(person_id, version) as person_id + FROM person_distinct_id2 + WHERE team_id = 2 + AND distinct_id IN + (SELECT distinct_id + FROM events + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') ) + GROUP BY distinct_id + HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + AND (1=1) ))) + WHERE step_0 = 1 )) + GROUP BY aggregation_target, + steps, + prop + HAVING steps = max_steps) + WHERE steps IN [1, 2, 3] + AND arrayFlatten(array(prop)) = arrayFlatten(array('finance')) + ORDER BY aggregation_target + LIMIT 100 + OFFSET 0 SETTINGS max_ast_elements=1000000, + max_expanded_ast_elements=1000000 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.3 + ''' + + SELECT replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS value, + count(*) as count + FROM events e + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND event IN ['buy', 'play movie', 'sign up'] + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + GROUP BY value + ORDER BY count DESC, value DESC + LIMIT 26 + OFFSET 0 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.4 + ''' + + SELECT aggregation_target AS actor_id + FROM + (SELECT aggregation_target, + steps, + avg(step_1_conversion_time) step_1_average_conversion_time_inner, + avg(step_2_conversion_time) step_2_average_conversion_time_inner, + median(step_1_conversion_time) step_1_median_conversion_time_inner, + median(step_2_conversion_time) step_2_median_conversion_time_inner, + prop + FROM + (SELECT aggregation_target, + steps, + max(steps) over (PARTITION BY aggregation_target, + prop) as max_steps, + step_1_conversion_time, + step_2_conversion_time, + prop + FROM + (SELECT *, + if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY + AND latest_1 <= latest_2 + AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps, + if(isNotNull(latest_1) + AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, + if(isNotNull(latest_2) + AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time + FROM + (SELECT aggregation_target, timestamp, step_0, + latest_0, + step_1, + min(latest_1) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) latest_1, + step_2, + min(latest_2) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) latest_2 , + if(has(['technology', 'finance'], prop), prop, 'Other') as prop + FROM + (SELECT *, + prop_vals as prop + FROM + (SELECT e.timestamp as timestamp, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as aggregation_target, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as person_id, + if(event = 'sign up', 1, 0) as step_0, + if(step_0 = 1, timestamp, null) as latest_0, + if(event = 'play movie', 1, 0) as step_1, + if(step_1 = 1, timestamp, null) as latest_1, + if(event = 'buy', 1, 0) as step_2, + if(step_2 = 1, timestamp, null) as latest_2, + replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS prop_basic, + prop_basic as prop, + argMinIf(prop, timestamp, isNotNull(prop)) over (PARTITION by aggregation_target) as prop_vals + FROM events e + LEFT OUTER JOIN + (SELECT distinct_id, + argMax(person_id, version) as person_id + FROM person_distinct_id2 + WHERE team_id = 2 + AND distinct_id IN + (SELECT distinct_id + FROM events + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') ) + GROUP BY distinct_id + HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + AND (1=1) ))) + WHERE step_0 = 1 )) + GROUP BY aggregation_target, + steps, + prop + HAVING steps = max_steps) + WHERE steps IN [2, 3] + AND arrayFlatten(array(prop)) = arrayFlatten(array('finance')) + ORDER BY aggregation_target + LIMIT 100 + OFFSET 0 SETTINGS max_ast_elements=1000000, + max_expanded_ast_elements=1000000 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.5 + ''' + + SELECT replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS value, + count(*) as count + FROM events e + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND event IN ['buy', 'play movie', 'sign up'] + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + GROUP BY value + ORDER BY count DESC, value DESC + LIMIT 26 + OFFSET 0 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.6 + ''' + + SELECT aggregation_target AS actor_id + FROM + (SELECT aggregation_target, + steps, + avg(step_1_conversion_time) step_1_average_conversion_time_inner, + avg(step_2_conversion_time) step_2_average_conversion_time_inner, + median(step_1_conversion_time) step_1_median_conversion_time_inner, + median(step_2_conversion_time) step_2_median_conversion_time_inner, + prop + FROM + (SELECT aggregation_target, + steps, + max(steps) over (PARTITION BY aggregation_target, + prop) as max_steps, + step_1_conversion_time, + step_2_conversion_time, + prop + FROM + (SELECT *, + if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY + AND latest_1 <= latest_2 + AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps, + if(isNotNull(latest_1) + AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, + if(isNotNull(latest_2) + AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time + FROM + (SELECT aggregation_target, timestamp, step_0, + latest_0, + step_1, + min(latest_1) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) latest_1, + step_2, + min(latest_2) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) latest_2 , + if(has(['technology', 'finance'], prop), prop, 'Other') as prop + FROM + (SELECT *, + prop_vals as prop + FROM + (SELECT e.timestamp as timestamp, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as aggregation_target, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as person_id, + if(event = 'sign up', 1, 0) as step_0, + if(step_0 = 1, timestamp, null) as latest_0, + if(event = 'play movie', 1, 0) as step_1, + if(step_1 = 1, timestamp, null) as latest_1, + if(event = 'buy', 1, 0) as step_2, + if(step_2 = 1, timestamp, null) as latest_2, + replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS prop_basic, + prop_basic as prop, + argMinIf(prop, timestamp, isNotNull(prop)) over (PARTITION by aggregation_target) as prop_vals + FROM events e + LEFT OUTER JOIN + (SELECT distinct_id, + argMax(person_id, version) as person_id + FROM person_distinct_id2 + WHERE team_id = 2 + AND distinct_id IN + (SELECT distinct_id + FROM events + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') ) + GROUP BY distinct_id + HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + AND (1=1) ))) + WHERE step_0 = 1 )) + GROUP BY aggregation_target, + steps, + prop + HAVING steps = max_steps) + WHERE steps IN [1, 2, 3] + AND arrayFlatten(array(prop)) = arrayFlatten(array('technology')) + ORDER BY aggregation_target + LIMIT 100 + OFFSET 0 SETTINGS max_ast_elements=1000000, + max_expanded_ast_elements=1000000 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.7 + ''' + + SELECT replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS value, + count(*) as count + FROM events e + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND event IN ['buy', 'play movie', 'sign up'] + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + GROUP BY value + ORDER BY count DESC, value DESC + LIMIT 26 + OFFSET 0 + ''' +# --- +# name: TestStrictFunnelGroupBreakdownUDF.test_funnel_breakdown_group.8 + ''' + + SELECT aggregation_target AS actor_id + FROM + (SELECT aggregation_target, + steps, + avg(step_1_conversion_time) step_1_average_conversion_time_inner, + avg(step_2_conversion_time) step_2_average_conversion_time_inner, + median(step_1_conversion_time) step_1_median_conversion_time_inner, + median(step_2_conversion_time) step_2_median_conversion_time_inner, + prop + FROM + (SELECT aggregation_target, + steps, + max(steps) over (PARTITION BY aggregation_target, + prop) as max_steps, + step_1_conversion_time, + step_2_conversion_time, + prop + FROM + (SELECT *, + if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY + AND latest_1 <= latest_2 + AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 + AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps, + if(isNotNull(latest_1) + AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, + if(isNotNull(latest_2) + AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time + FROM + (SELECT aggregation_target, timestamp, step_0, + latest_0, + step_1, + min(latest_1) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) latest_1, + step_2, + min(latest_2) over (PARTITION by aggregation_target, + prop + ORDER BY timestamp DESC ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) latest_2 , + if(has(['technology', 'finance'], prop), prop, 'Other') as prop + FROM + (SELECT *, + prop_vals as prop + FROM + (SELECT e.timestamp as timestamp, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as aggregation_target, + if(notEmpty(pdi.distinct_id), pdi.person_id, e.person_id) as person_id, + if(event = 'sign up', 1, 0) as step_0, + if(step_0 = 1, timestamp, null) as latest_0, + if(event = 'play movie', 1, 0) as step_1, + if(step_1 = 1, timestamp, null) as latest_1, + if(event = 'buy', 1, 0) as step_2, + if(step_2 = 1, timestamp, null) as latest_2, + replaceRegexpAll(JSONExtractRaw(group_properties_0, 'industry'), '^"|"$', '') AS prop_basic, + prop_basic as prop, + argMinIf(prop, timestamp, isNotNull(prop)) over (PARTITION by aggregation_target) as prop_vals + FROM events e + LEFT OUTER JOIN + (SELECT distinct_id, + argMax(person_id, version) as person_id + FROM person_distinct_id2 + WHERE team_id = 2 + AND distinct_id IN + (SELECT distinct_id + FROM events + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') ) + GROUP BY distinct_id + HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id + LEFT JOIN + (SELECT group_key, + argMax(group_properties, _timestamp) AS group_properties_0 + FROM groups + WHERE team_id = 2 + AND group_type_index = 0 + GROUP BY group_key) groups_0 ON "$group_0" == groups_0.group_key + WHERE team_id = 2 + AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC') + AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-08 23:59:59', 'UTC') + AND (1=1) ))) + WHERE step_0 = 1 )) + GROUP BY aggregation_target, + steps, + prop + HAVING steps = max_steps) + WHERE steps IN [2, 3] + AND arrayFlatten(array(prop)) = arrayFlatten(array('technology')) + ORDER BY aggregation_target + LIMIT 100 + OFFSET 0 SETTINGS max_ast_elements=1000000, + max_expanded_ast_elements=1000000 + ''' +# --- diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends.ambr index 16be898651577..a8ce810a87cfd 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends.ambr @@ -1,366 +1,4 @@ # serializer version: 1 -# name: BaseTestFunnelTrends.test_timezones_trends - ''' - SELECT fill.entrance_period_start AS entrance_period_start, - data.reached_from_step_count AS reached_from_step_count, - data.reached_to_step_count AS reached_to_step_count, - if(ifNull(greater(data.reached_from_step_count, 0), 0), round(multiply(divide(data.reached_to_step_count, data.reached_from_step_count), 100), 2), 0) AS conversion_rate - FROM - (SELECT plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-04-30 00:00:00'), 6, 'UTC'))), toIntervalDay(period_offsets.number)) AS entrance_period_start - FROM numbers(plus(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-04-30 00:00:00'), 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-05-07 23:59:59'), 6, 'UTC')))), 1)) AS period_offsets) AS fill - LEFT OUTER JOIN - (SELECT entrance_period_start AS entrance_period_start, - countIf(ifNull(greaterOrEquals(steps_completed, 1), 0)) AS reached_from_step_count, - countIf(ifNull(greaterOrEquals(steps_completed, 3), 0)) AS reached_to_step_count - FROM - (SELECT aggregation_target AS aggregation_target, - toStartOfDay(timestamp) AS entrance_period_start, - max(steps) AS steps_completed - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-04-30 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-07 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0)) - GROUP BY aggregation_target, - entrance_period_start) - GROUP BY entrance_period_start) AS data ON equals(data.entrance_period_start, fill.entrance_period_start) - ORDER BY fill.entrance_period_start ASC - LIMIT 1000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=4000000, - max_expanded_ast_elements=4000000, - max_bytes_before_external_group_by=23622320128, - allow_experimental_analyzer=1 - ''' -# --- -# name: BaseTestFunnelTrends.test_timezones_trends.1 - ''' - SELECT fill.entrance_period_start AS entrance_period_start, - data.reached_from_step_count AS reached_from_step_count, - data.reached_to_step_count AS reached_to_step_count, - if(ifNull(greater(data.reached_from_step_count, 0), 0), round(multiply(divide(data.reached_to_step_count, data.reached_from_step_count), 100), 2), 0) AS conversion_rate - FROM - (SELECT plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-04-30 00:00:00'), 6, 'US/Pacific'))), toIntervalDay(period_offsets.number)) AS entrance_period_start - FROM numbers(plus(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-04-30 00:00:00'), 6, 'US/Pacific'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-05-07 23:59:59'), 6, 'US/Pacific')))), 1)) AS period_offsets) AS fill - LEFT OUTER JOIN - (SELECT entrance_period_start AS entrance_period_start, - countIf(ifNull(greaterOrEquals(steps_completed, 1), 0)) AS reached_from_step_count, - countIf(ifNull(greaterOrEquals(steps_completed, 3), 0)) AS reached_to_step_count - FROM - (SELECT aggregation_target AS aggregation_target, - toStartOfDay(timestamp) AS entrance_period_start, - max(steps) AS steps_completed - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'US/Pacific') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'US/Pacific'), toDateTime64('2021-04-30 00:00:00.000000', 6, 'US/Pacific')), lessOrEquals(toTimeZone(e.timestamp, 'US/Pacific'), toDateTime64('2021-05-07 23:59:59.999999', 6, 'US/Pacific'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0)) - GROUP BY aggregation_target, - entrance_period_start) - GROUP BY entrance_period_start) AS data ON equals(data.entrance_period_start, fill.entrance_period_start) - ORDER BY fill.entrance_period_start ASC - LIMIT 1000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=4000000, - max_expanded_ast_elements=4000000, - max_bytes_before_external_group_by=23622320128, - allow_experimental_analyzer=1 - ''' -# --- -# name: BaseTestFunnelTrends.test_week_interval - ''' - SELECT fill.entrance_period_start AS entrance_period_start, - data.reached_from_step_count AS reached_from_step_count, - data.reached_to_step_count AS reached_to_step_count, - if(ifNull(greater(data.reached_from_step_count, 0), 0), round(multiply(divide(data.reached_to_step_count, data.reached_from_step_count), 100), 2), 0) AS conversion_rate - FROM - (SELECT plus(toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-05-01 00:00:00'), 6, 'UTC')), 0), toIntervalWeek(period_offsets.number)) AS entrance_period_start - FROM numbers(plus(dateDiff('week', toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-05-01 00:00:00'), 6, 'UTC')), 0), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull(('2021-05-07 23:59:59'), 6, 'UTC')), 0)), 1)) AS period_offsets) AS fill - LEFT OUTER JOIN - (SELECT entrance_period_start AS entrance_period_start, - countIf(ifNull(greaterOrEquals(steps_completed, 1), 0)) AS reached_from_step_count, - countIf(ifNull(greaterOrEquals(steps_completed, 3), 0)) AS reached_to_step_count - FROM - (SELECT aggregation_target AS aggregation_target, - toStartOfWeek(timestamp, 0) AS entrance_period_start, - max(steps) AS steps_completed - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-07 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0)) - GROUP BY aggregation_target, - entrance_period_start) - GROUP BY entrance_period_start) AS data ON equals(data.entrance_period_start, fill.entrance_period_start) - ORDER BY fill.entrance_period_start ASC - LIMIT 1000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=4000000, - max_expanded_ast_elements=4000000, - max_bytes_before_external_group_by=23622320128, - allow_experimental_analyzer=1 - ''' -# --- -# name: BaseTestFunnelTrends.test_week_interval.1 - ''' - - SELECT aggregation_target AS actor_id - FROM - (SELECT aggregation_target, - toStartOfWeek(toTimeZone(toDateTime(timestamp, 'UTC'), 'UTC'), 0) AS entrance_period_start, - max(steps) AS steps_completed - FROM - (SELECT *, - if(latest_0 <= latest_1 - AND latest_1 <= latest_0 + INTERVAL 7 DAY - AND latest_1 <= latest_2 - AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 - AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps , - if(isNotNull(latest_1) - AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, - if(isNotNull(latest_2) - AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - latest_1, - step_2, - min(latest_2) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_2 - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - latest_1, - step_2, - if(latest_2 < latest_1, NULL, latest_2) as latest_2 - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - min(latest_1) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_1, - step_2, - min(latest_2) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_2 - FROM - (SELECT e.timestamp as timestamp, - pdi.person_id as aggregation_target, - pdi.person_id as person_id, - if(event = 'step one', 1, 0) as step_0, - if(step_0 = 1, timestamp, null) as latest_0, - if(event = 'step two', 1, 0) as step_1, - if(step_1 = 1, timestamp, null) as latest_1, - if(event = 'step three', 1, 0) as step_2, - if(step_2 = 1, timestamp, null) as latest_2 - FROM events e - INNER JOIN - (SELECT distinct_id, - argMax(person_id, version) as person_id - FROM person_distinct_id2 - WHERE team_id = 2 - AND distinct_id IN - (SELECT distinct_id - FROM events - WHERE team_id = 2 - AND event IN ['step one', 'step three', 'step two'] - AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-05-01 00:00:00', 'UTC') - AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-05-07 23:59:59', 'UTC') ) - GROUP BY distinct_id - HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id - WHERE team_id = 2 - AND event IN ['step one', 'step three', 'step two'] - AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-05-01 00:00:00', 'UTC') - AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-05-07 23:59:59', 'UTC') - AND (step_0 = 1 - OR step_1 = 1 - OR step_2 = 1) )))) - WHERE step_0 = 1 ) - WHERE toDateTime(entrance_period_start) = '2021-04-25 00:00:00' - GROUP BY aggregation_target, - entrance_period_start) - WHERE steps_completed >= 3 - ORDER BY aggregation_target - LIMIT 100 - OFFSET 0 SETTINGS max_ast_elements=1000000, - max_expanded_ast_elements=1000000 - ''' -# --- # name: TestFunnelTrends.test_timezones_trends ''' SELECT fill.entrance_period_start AS entrance_period_start, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr index 8467ca0eff992..3bc57fc96fc6a 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr @@ -7,7 +7,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends_v0(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends_v1(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'UTC') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown @@ -15,14 +15,8 @@ (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2 + if(equals(e.event, 'step three'), 1, 0) AS step_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -58,7 +52,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends_v0(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends_v1(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'US/Pacific') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown @@ -66,14 +60,8 @@ (SELECT toTimeZone(e.timestamp, 'US/Pacific') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2 + if(equals(e.event, 'step three'), 1, 0) AS step_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -109,7 +97,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends_v0(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfWeek(timestamp, 0), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends_v1(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfWeek(timestamp, 0), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'UTC') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown @@ -117,14 +105,8 @@ (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2 + if(equals(e.event, 'step three'), 1, 0) AS step_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr index 82dd4f740c62b..7d2c9dfd6e82d 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr @@ -11,30 +11,29 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2 + if(equals(e.event, 'step three'), 1, 0) AS step_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -45,7 +44,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -68,84 +67,33 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, - avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, - median(step_1_conversion_time) AS step_1_median_conversion_time_inner, - median(step_2_conversion_time) AS step_2_median_conversion_time_inner + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, - step_1_conversion_time AS step_1_conversion_time, - step_2_conversion_time AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalSecond(15))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalSecond(15))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalSecond(15))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalSecond(15))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalSecond(15))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'step one'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'step two'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(equals(e.event, 'step three'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0))) - GROUP BY aggregation_target, - steps - HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) - and isNull(max(max_steps)))) - WHERE ifNull(in(steps, [2, 3]), 0) + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'step one'), 1, 0) AS step_0, + if(equals(e.event, 'step two'), 1, 0) AS step_1, + if(equals(e.event, 'step three'), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2021-05-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('step one', 'step three', 'step two'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 1), 0) ORDER BY aggregation_target ASC) AS source INNER JOIN (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, @@ -187,30 +135,29 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, '$autocapture'), match(e.elements_chain, '(^|;)button(\\.|$|;|:)'), arrayExists(x -> ifNull(equals(x, 'Pay $10'), 0), e.elements_chain_texts)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(and(equals(e.event, '$autocapture'), match(e.elements_chain, '(^|;)a(\\.|$|;|:)'), equals(e.elements_chain_href, '/movie')), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2 + if(and(equals(e.event, '$autocapture'), match(e.elements_chain, '(^|;)a(\\.|$|;|:)'), equals(e.elements_chain_href, '/movie')), 1, 0) AS step_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -221,7 +168,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2011-12-25 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2012-01-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$autocapture', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -264,28 +211,29 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(and(equals(e.event, 'user signed up'), ifNull(in(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), (SELECT cohortpeople.person_id AS person_id FROM cohortpeople WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2), equals(cohortpeople.version, 0)))), 0)), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'paid'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1 + if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -296,7 +244,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -322,30 +270,29 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2 + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -367,7 +314,7 @@ HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -390,95 +337,44 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, - avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, - median(step_1_conversion_time) AS step_1_median_conversion_time_inner, - median(step_2_conversion_time) AS step_2_median_conversion_time_inner + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, - step_1_conversion_time AS step_1_conversion_time, - step_2_conversion_time AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'user signed up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'age'), ''), 'null'), '^"|"$', '') AS properties___age - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0))) - GROUP BY aggregation_target, - steps - HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) - and isNull(max(max_steps)))) - WHERE ifNull(in(steps, [1, 2, 3]), 0) + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'age'), ''), 'null'), '^"|"$', '') AS properties___age + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 0), 0) ORDER BY aggregation_target ASC) AS source INNER JOIN (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, @@ -508,95 +404,44 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, - avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, - median(step_1_conversion_time) AS step_1_median_conversion_time_inner, - median(step_2_conversion_time) AS step_2_median_conversion_time_inner + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, - step_1_conversion_time AS step_1_conversion_time, - step_2_conversion_time AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'user signed up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'age'), ''), 'null'), '^"|"$', '') AS properties___age - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0))) - GROUP BY aggregation_target, - steps - HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) - and isNull(max(max_steps)))) - WHERE ifNull(in(steps, [2, 3]), 0) + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'age'), ''), 'null'), '^"|"$', '') AS properties___age + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 1), 0) ORDER BY aggregation_target ASC) AS source INNER JOIN (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, @@ -626,95 +471,44 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - avg(step_1_conversion_time) AS step_1_average_conversion_time_inner, - avg(step_2_conversion_time) AS step_2_average_conversion_time_inner, - median(step_1_conversion_time) AS step_1_median_conversion_time_inner, - median(step_2_conversion_time) AS step_2_median_conversion_time_inner + (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, + af_tuple.2 AS breakdown, + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM - (SELECT aggregation_target AS aggregation_target, - steps AS steps, - max(steps) OVER (PARTITION BY aggregation_target) AS max_steps, - step_1_conversion_time AS step_1_conversion_time, - step_2_conversion_time AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0), ifNull(lessOrEquals(latest_1, latest_2), 0), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 3, if(and(ifNull(lessOrEquals(latest_0, latest_1), 0), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), 2, 1)) AS steps, - if(and(isNotNull(latest_1), ifNull(lessOrEquals(latest_1, plus(toTimeZone(latest_0, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_0, latest_1), NULL) AS step_1_conversion_time, - if(and(isNotNull(latest_2), ifNull(lessOrEquals(latest_2, plus(toTimeZone(latest_1, 'UTC'), toIntervalDay(14))), 0)), dateDiff('second', latest_1, latest_2), NULL) AS step_2_conversion_time - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - if(ifNull(less(latest_2, latest_1), 0), NULL, latest_2) AS latest_2 - FROM - (SELECT aggregation_target AS aggregation_target, - timestamp AS timestamp, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - min(latest_1) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_1, - step_2 AS step_2, - min(latest_2) OVER (PARTITION BY aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) AS latest_2 - FROM - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - if(equals(e.event, 'user signed up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2 - FROM events AS e - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'age'), ''), 'null'), '^"|"$', '') AS properties___age - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) - WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))))) - WHERE ifNull(equals(step_0, 1), 0))) - GROUP BY aggregation_target, - steps - HAVING ifNull(equals(steps, max(max_steps)), isNull(steps) - and isNull(max(max_steps)))) - WHERE ifNull(in(steps, [3]), 0) + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, + if(equals(e.event, 'user signed up'), 1, 0) AS step_0, + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha.com'), 0)), 1, 0) AS step_1, + if(and(equals(e.event, '$pageview'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'aloha2.com'), 0)), 1, 0) AS step_2 + FROM events AS e + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'age'), ''), 'null'), '^"|"$', '') AS properties___age + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__person ON equals(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), e__person.id) + WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-07-01 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('$pageview', 'user signed up')), or(and(ifNull(ilike(e__person.properties___email, '%.com%'), 0), ifNull(equals(e__person.properties___age, '20'), 0)), or(ifNull(ilike(e__person.properties___email, '%.org%'), 0), ifNull(equals(e__person.properties___age, '28'), 0)))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0)))) + GROUP BY aggregation_target + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + WHERE ifNull(greaterOrEquals(step_reached, 2), 0) ORDER BY aggregation_target ASC) AS source INNER JOIN (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, @@ -753,28 +547,29 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(and(equals(e.event, 'user signed up'), ifNull(in(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), (SELECT person_static_cohort.person_id AS person_id FROM person_static_cohort WHERE and(equals(person_static_cohort.team_id, 2), equals(person_static_cohort.cohort_id, 2)))), 0)), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'paid'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1 + if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -785,7 +580,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -808,25 +603,26 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'US/Pacific') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, - if(equals(e.event, 'paid'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1 + if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e LEFT OUTER JOIN (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, @@ -837,7 +633,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'US/Pacific'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'US/Pacific')), lessOrEquals(toTimeZone(e.timestamp, 'US/Pacific'), toDateTime64('2020-01-14 23:59:59.999999', 6, 'US/Pacific'))), in(e.event, tuple('paid', 'user signed up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0)))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -860,38 +656,38 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -905,7 +701,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('buy', 'sign up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -928,40 +724,40 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'step_1', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'step_1', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - prop_basic AS prop_basic, - prop_0 AS prop_0, - prop_1 AS prop_1, - prop, - prop_vals AS prop_vals, - prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop_0 AS prop_0, + prop_1 AS prop_1, + prop, + prop_vals AS prop_vals, + prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, if(ifNull(equals(step_0, 1), 0), prop_basic, []) AS prop_0, if(ifNull(equals(step_1, 1), 0), prop_basic, []) AS prop_1, @@ -980,7 +776,7 @@ WHERE ifNull(notEquals(prop, []), isNotNull(prop) or isNotNull([]))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1003,38 +799,38 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'buy'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, - 0 AS exclusion_0, - 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), ''), ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1048,7 +844,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('buy', 'sign up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1074,46 +870,42 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - exclusion_2 AS exclusion_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1128,7 +920,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('buy', 'play movie', 'sign up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1154,46 +946,42 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - exclusion_2 AS exclusion_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e.`$group_0` AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1208,7 +996,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('buy', 'play movie', 'sign up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1234,46 +1022,42 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS af, + (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS step_reached, + plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, - af_tuple.3 AS timings + af_tuple.3 AS timings, + aggregation_target AS aggregation_target FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - step_0 AS step_0, - latest_0 AS latest_0, - step_1 AS step_1, - latest_1 AS latest_1, - step_2 AS step_2, - latest_2 AS latest_2, - exclusion_0 AS exclusion_0, - exclusion_1 AS exclusion_1, - exclusion_2 AS exclusion_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + uuid AS uuid, + `$session_id` AS `$session_id`, + `$window_id` AS `$window_id`, + step_0 AS step_0, + step_1 AS step_1, + step_2 AS step_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, + e.uuid AS uuid, + e.`$session_id` AS `$session_id`, + e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, - if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, - if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, - if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, - 0 AS exclusion_0, - 0 AS exclusion_1, - 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1295,7 +1079,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC'))), in(e.event, tuple('buy', 'play movie', 'sign up'))), or(ifNull(equals(step_0, 1), 0), ifNull(equals(step_1, 1), 0), ifNull(equals(step_2, 1), 0))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(af, 0), 0)) + HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation.py index da85943dcd894..44b92a5579b4a 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation.py @@ -1,5 +1,6 @@ from typing import Any, cast import unittest +from unittest import skip from freezegun import freeze_time from rest_framework.exceptions import ValidationError @@ -10,7 +11,7 @@ EventStats, FunnelCorrelationQueryRunner, ) -from posthog.hogql_queries.insights.funnels.test.test_funnel_correlations_persons import get_actors +from posthog.hogql_queries.insights.funnels.test.test_funnel_correlation_actors import get_actors from posthog.hogql_queries.legacy_compatibility.filter_to_query import filter_to_query from posthog.models.action import Action from posthog.models.element import Element @@ -49,7 +50,8 @@ def _create_action(**kwargs): return action -class TestClickhouseFunnelCorrelation(ClickhouseTestMixin, APIBaseTest): +class BaseTestClickhouseFunnelCorrelation(ClickhouseTestMixin, APIBaseTest): + __test__ = False maxDiff = None def _get_events_for_filters( @@ -1206,6 +1208,7 @@ def test_correlation_with_properties_raises_validation_error(self): @also_test_with_materialized_columns( event_properties=[], person_properties=["$browser"], verify_no_jsonextract=False ) + @skip("Works locally and works after you tmate onto github actions and run it, but fails in CI") def test_correlation_with_multiple_properties(self): filters = { "events": [ @@ -1303,6 +1306,11 @@ def test_correlation_with_multiple_properties(self): timestamp="2020-01-04T14:00:00Z", ) + result, _ = self._get_events_for_filters( + filters, + funnelCorrelationType=FunnelCorrelationResultsType.PROPERTIES, + funnelCorrelationNames=["$browser", "$nice"], + ) result, _ = self._get_events_for_filters( filters, funnelCorrelationType=FunnelCorrelationResultsType.PROPERTIES, @@ -2076,6 +2084,10 @@ def test_funnel_correlation_with_event_properties_autocapture(self): # ) +class TestClickhouseFunnelCorrelation(BaseTestClickhouseFunnelCorrelation): + __test__ = True + + class TestCorrelationFunctions(unittest.TestCase): def test_are_results_insignificant(self): # Same setup as above test: test_discarding_insignificant_events diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_correlations_persons.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors.py similarity index 98% rename from posthog/hogql_queries/insights/funnels/test/test_funnel_correlations_persons.py rename to posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors.py index a6694deed8330..594d075b426d5 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_correlations_persons.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors.py @@ -7,6 +7,7 @@ from posthog.constants import INSIGHT_FUNNELS from posthog.hogql_queries.actors_query_runner import ActorsQueryRunner +from posthog.hogql_queries.insights.funnels.funnels_query_runner import FunnelsQueryRunner from posthog.hogql_queries.legacy_compatibility.filter_to_query import filter_to_query from posthog.models.team.team import Team from posthog.schema import ( @@ -73,7 +74,8 @@ def get_actors( return response.results -class TestFunnelCorrelationsActors(ClickhouseTestMixin, APIBaseTest): +class BaseTestFunnelCorrelationActors(ClickhouseTestMixin, APIBaseTest): + __test__ = False maxDiff = None def _setup_basic_test(self): @@ -575,6 +577,8 @@ def test_strict_funnel_correlation_with_recordings(self): {"id": "insight analyzed", "order": 1}, ], } + query = cast(FunnelsQuery, filter_to_query(filters)) + results = FunnelsQueryRunner(query=query, team=self.team).calculate().results results = get_actors( filters, @@ -641,3 +645,7 @@ def test_strict_funnel_correlation_with_recordings(self): } ], ) + + +class TestFunnelCorrelationActors(BaseTestFunnelCorrelationActors): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors_udf.py new file mode 100644 index 0000000000000..aa562e0260b73 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_actors_udf.py @@ -0,0 +1,9 @@ +from unittest.mock import Mock, patch + +from posthog.hogql_queries.insights.funnels.test.test_funnel_correlation_actors import BaseTestFunnelCorrelationActors +from posthog.hogql_queries.insights.funnels.test.test_funnel_udf import use_udf_funnel_flag_side_effect + + +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) +class TestFunnelCorrelationsActorsUDF(BaseTestFunnelCorrelationActors): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_udf.py new file mode 100644 index 0000000000000..0882bad888059 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_correlation_udf.py @@ -0,0 +1,9 @@ +from unittest.mock import Mock, patch + +from posthog.hogql_queries.insights.funnels.test.test_funnel_correlation import BaseTestClickhouseFunnelCorrelation +from posthog.hogql_queries.insights.funnels.test.test_funnel_udf import use_udf_funnel_flag_side_effect + + +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) +class TestClickhouseFunnelCorrelationUDF(BaseTestClickhouseFunnelCorrelation): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_persons.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_persons.py index e240e54f3f963..c62fefddcc57c 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_persons.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_persons.py @@ -60,7 +60,9 @@ def get_actors( return response.results -class TestFunnelPersons(ClickhouseTestMixin, APIBaseTest): +class BaseTestFunnelPersons(ClickhouseTestMixin, APIBaseTest): + __test__ = False + def _create_sample_data_multiple_dropoffs(self): for i in range(35): bulk_create_persons([{"distinct_ids": [f"user_{i}"], "team_id": self.team.pk}]) @@ -809,3 +811,7 @@ def test_first_time_math_multiple_ids(self): self.assertEqual(len(results), 2) self.assertCountEqual(set(results[0][1]["distinct_ids"]), {"person1", "anon1"}) self.assertCountEqual(set(results[1][1]["distinct_ids"]), {"person2", "anon2"}) + + +class TestFunnelPersons(BaseTestFunnelPersons): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_persons_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_persons_udf.py new file mode 100644 index 0000000000000..14c5144fc7610 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_persons_udf.py @@ -0,0 +1,31 @@ +from unittest.mock import patch, Mock + + +from posthog.constants import INSIGHT_FUNNELS +from posthog.hogql_queries.insights.funnels.test.test_funnel_persons import ( + get_actors, + BaseTestFunnelPersons, +) +from posthog.hogql_queries.insights.funnels.test.test_funnel_udf import use_udf_funnel_flag_side_effect + + +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) +class TestFunnelPersonsUDF(BaseTestFunnelPersons): + __test__ = True + + @patch("posthog.hogql_queries.insights.funnels.funnel_udf.FunnelUDF.actor_query", return_value=None) + def test_uses_udf(self, obj): + self._create_sample_data_multiple_dropoffs() + filters = { + "insight": INSIGHT_FUNNELS, + "interval": "day", + "date_from": "2021-05-01 00:00:00", + "date_to": "2021-05-07 00:00:00", + "funnel_window_days": 7, + "events": [ + {"id": "step one", "order": 0}, + {"id": "step two", "order": 1}, + {"id": "step three", "order": 2}, + ], + } + self.assertRaises(Exception, lambda: get_actors(filters, self.team, funnel_step=1)) diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict.py index 7be35d81324d1..dbc215fbb5f6a 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict.py @@ -48,6 +48,7 @@ class BaseTestFunnelStrictStepsBreakdown( _create_person, ), ): + __test__ = False maxDiff = None def test_basic_funnel_default_funnel_days_breakdown_event(self): @@ -186,7 +187,7 @@ class BaseTestStrictFunnelGroupBreakdown( ClickhouseFunnelStrictActors, ), ): - pass + __test__ = False class BaseTestFunnelStrictStepsConversionTime( @@ -194,11 +195,12 @@ class BaseTestFunnelStrictStepsConversionTime( funnel_conversion_time_test_factory(FunnelOrderType.ORDERED, ClickhouseFunnelStrictActors), # type: ignore ): maxDiff = None - pass + __test__ = False class BaseTestFunnelStrictSteps(ClickhouseTestMixin, APIBaseTest): maxDiff = None + __test__ = False def _get_actor_ids_at_step(self, filter, funnel_step, breakdown_value=None): filter = Filter(data=filter, team=self.team) @@ -629,19 +631,19 @@ def test_basic_strict_funnel_conversion_times(self): @patch("posthoganalytics.feature_enabled", new=Mock(return_value=False)) class TestFunnelStrictStepsBreakdown(BaseTestFunnelStrictStepsBreakdown): - pass + __test__ = True @patch("posthoganalytics.feature_enabled", new=Mock(return_value=False)) class TestFunnelStrictSteps(BaseTestFunnelStrictSteps): - pass + __test__ = True @patch("posthoganalytics.feature_enabled", new=Mock(return_value=False)) class TestStrictFunnelGroupBreakdown(BaseTestStrictFunnelGroupBreakdown): - pass + __test__ = True @patch("posthoganalytics.feature_enabled", new=Mock(return_value=False)) class TestFunnelStrictStepsConversionTime(BaseTestFunnelStrictStepsConversionTime): - pass + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons.py index 33fcdea328426..311fa1c76ccf4 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons.py @@ -20,7 +20,9 @@ FORMAT_TIME = "%Y-%m-%d 00:00:00" -class TestFunnelStrictStepsPersons(ClickhouseTestMixin, APIBaseTest): +class BaseTestFunnelStrictStepsPersons(ClickhouseTestMixin, APIBaseTest): + __test__ = False + def _create_sample_data_multiple_dropoffs(self): events_by_person = {} for i in range(5): @@ -265,3 +267,7 @@ def test_strict_funnel_person_recordings(self): } ], ) + + +class TestFunnelStrictStepsPersons(BaseTestFunnelStrictStepsPersons): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons_udf.py new file mode 100644 index 0000000000000..e28999447b524 --- /dev/null +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_persons_udf.py @@ -0,0 +1,9 @@ +from unittest.mock import patch, Mock + +from posthog.hogql_queries.insights.funnels.test.test_funnel_strict_persons import BaseTestFunnelStrictStepsPersons +from posthog.hogql_queries.insights.funnels.test.test_funnel_udf import use_udf_funnel_flag_side_effect + + +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) +class TestFunnelStrictStepsPersons(BaseTestFunnelStrictStepsPersons): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_udf.py index 178e329d3748e..fdde235e5bc7e 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_udf.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_strict_udf.py @@ -9,20 +9,20 @@ @patch("posthoganalytics.feature_enabled", new=Mock(return_value=True)) -class TestFunnelStrictStepsBreakdown(BaseTestFunnelStrictStepsBreakdown): - pass +class TestFunnelStrictStepsBreakdownUDF(BaseTestFunnelStrictStepsBreakdown): + __test__ = True @patch("posthoganalytics.feature_enabled", new=Mock(return_value=True)) -class TestFunnelStrictSteps(BaseTestFunnelStrictSteps): - pass +class TestFunnelStrictStepsUDF(BaseTestFunnelStrictSteps): + __test__ = True @patch("posthoganalytics.feature_enabled", new=Mock(return_value=True)) -class TestStrictFunnelGroupBreakdown(BaseTestStrictFunnelGroupBreakdown): - pass +class TestStrictFunnelGroupBreakdownUDF(BaseTestStrictFunnelGroupBreakdown): + __test__ = True @patch("posthoganalytics.feature_enabled", new=Mock(return_value=True)) -class TestFunnelStrictStepsConversionTime(BaseTestFunnelStrictStepsConversionTime): - pass +class TestFunnelStrictStepsConversionTimeUDF(BaseTestFunnelStrictStepsConversionTime): + __test__ = True diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_trends.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_trends.py index 446a529113f9f..d7f8d326e2a7d 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_trends.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_trends.py @@ -1,6 +1,5 @@ from datetime import date, datetime, timedelta from typing import cast -from unittest.mock import patch, Mock from zoneinfo import ZoneInfo from freezegun.api import freeze_time @@ -1615,11 +1614,10 @@ def test_parses_breakdown_correctly(self): self.assertEqual(len(results), 1) -@patch("posthoganalytics.feature_enabled", new=Mock(return_value=False)) class TestFunnelTrends(BaseTestFunnelTrends): __test__ = True - def test_assert_flag_is_working(self): + def test_assert_udf_flag_is_working(self): filters = { "insight": INSIGHT_FUNNELS, "funnel_viz_type": "trends", diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_trends_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_trends_udf.py index 0b28f49fb952c..2829bb93ce7dc 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_trends_udf.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_trends_udf.py @@ -15,7 +15,7 @@ class TestFunnelTrendsUDF(BaseTestFunnelTrends): __test__ = True - def test_assert_trends_flag_is_on(self): + def test_assert_udf_flag_is_working(self): filters = { "insight": INSIGHT_FUNNELS, "funnel_viz_type": "trends", diff --git a/posthog/hogql_queries/insights/funnels/test/test_funnel_udf.py b/posthog/hogql_queries/insights/funnels/test/test_funnel_udf.py index 849760ed262a3..5fba037657116 100644 --- a/posthog/hogql_queries/insights/funnels/test/test_funnel_udf.py +++ b/posthog/hogql_queries/insights/funnels/test/test_funnel_udf.py @@ -31,10 +31,10 @@ def _create_action(**kwargs): return action -funnel_flag_side_effect = lambda key, *args, **kwargs: key == "insight-funnels-use-udf" +use_udf_funnel_flag_side_effect = lambda key, *args, **kwargs: key == "insight-funnels-use-udf" -@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=funnel_flag_side_effect)) +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) class TestFunnelBreakdownUDF( ClickhouseTestMixin, funnel_breakdown_test_factory( # type: ignore @@ -48,7 +48,7 @@ class TestFunnelBreakdownUDF( pass -@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=funnel_flag_side_effect)) +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) class TestFunnelGroupBreakdownUDF( ClickhouseTestMixin, funnel_breakdown_group_test_factory( # type: ignore @@ -59,7 +59,7 @@ class TestFunnelGroupBreakdownUDF( pass -@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=funnel_flag_side_effect)) +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) class TestFOSSFunnelUDF(funnel_test_factory(Funnel, _create_event, _create_person)): # type: ignore def test_assert_flag_is_on(self): filters = { @@ -102,7 +102,7 @@ def test_assert_trends_flag_is_off(self): maxDiff = None -@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=funnel_flag_side_effect)) +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=use_udf_funnel_flag_side_effect)) class TestFunnelConversionTimeUDF( ClickhouseTestMixin, funnel_conversion_time_test_factory(FunnelOrderType.ORDERED, ClickhouseFunnelActors), # type: ignore diff --git a/posthog/hogql_queries/insights/funnels/utils.py b/posthog/hogql_queries/insights/funnels/utils.py index ba8425843e5ed..b071bcd7a1d86 100644 --- a/posthog/hogql_queries/insights/funnels/utils.py +++ b/posthog/hogql_queries/insights/funnels/utils.py @@ -1,10 +1,26 @@ from posthog.constants import FUNNEL_WINDOW_INTERVAL_TYPES from posthog.hogql import ast from posthog.hogql.parser import parse_expr +from posthog.hogql_queries.legacy_compatibility.feature_flag import ( + insight_funnels_use_udf_trends, + insight_funnels_use_udf, +) +from posthog.models import Team from posthog.schema import FunnelConversionWindowTimeUnit, FunnelVizType, FunnelsFilter, StepOrderValue from rest_framework.exceptions import ValidationError +def use_udf(funnelsFilter: FunnelsFilter, team: Team): + if funnelsFilter.useUdf: + return True + funnelVizType = funnelsFilter.funnelVizType + if funnelVizType == FunnelVizType.TRENDS and insight_funnels_use_udf_trends(team): + return True + if funnelVizType == FunnelVizType.STEPS and insight_funnels_use_udf(team): + return True + return False + + def get_funnel_order_class(funnelsFilter: FunnelsFilter, use_udf=False): from posthog.hogql_queries.insights.funnels import ( Funnel, @@ -22,8 +38,9 @@ def get_funnel_order_class(funnelsFilter: FunnelsFilter, use_udf=False): return Funnel -def get_funnel_actor_class(funnelsFilter: FunnelsFilter): +def get_funnel_actor_class(funnelsFilter: FunnelsFilter, use_udf=False): from posthog.hogql_queries.insights.funnels import ( + FunnelUDF, FunnelActors, FunnelStrictActors, FunnelUnorderedActors, @@ -34,6 +51,8 @@ def get_funnel_actor_class(funnelsFilter: FunnelsFilter): return FunnelTrendsActors if funnelsFilter.funnelOrderType == StepOrderValue.UNORDERED: return FunnelUnorderedActors + if use_udf: + return FunnelUDF if funnelsFilter.funnelOrderType == StepOrderValue.STRICT: return FunnelStrictActors return FunnelActors diff --git a/posthog/hogql_queries/insights/test/__snapshots__/test_paths_query_runner_ee.ambr b/posthog/hogql_queries/insights/test/__snapshots__/test_paths_query_runner_ee.ambr index e32831815ddea..326acba019703 100644 --- a/posthog/hogql_queries/insights/test/__snapshots__/test_paths_query_runner_ee.ambr +++ b/posthog/hogql_queries/insights/test/__snapshots__/test_paths_query_runner_ee.ambr @@ -1,4 +1,5931 @@ # serializer version: 1 +# name: ClickhousePathsUDF.test_end + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_end.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_end_materialized + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), nullIf(nullIf(events.`mat_$screen_name`, ''), 'null'), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_end_materialized.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), nullIf(nullIf(events.`mat_$screen_name`, ''), 'null'), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_exclusion_filters_with_wildcard_groups + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['/bar/*/foo'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['/bar/.*/foo']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), and(equals(events.event, '$pageview'), ifNull(notIn(path_item, ['/bar/*/foo']), 0))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_exclusion_filters_with_wildcard_groups.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['/xxx/invalid/*'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['/xxx/invalid/.*']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), and(equals(events.event, '$pageview'), ifNull(notIn(path_item, ['/bar/*/foo']), 0))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_inclusion_exclusion_filters + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_inclusion_exclusion_filters.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$screen')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_inclusion_exclusion_filters.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_inclusion_exclusion_filters.3 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), and(or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$'))), ifNull(notIn(path_item, ['/custom1', '/1', '/2', '/3']), 0))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_event_ordering + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-03 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_groups_filtering_person_on_events + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS events__group_0 ON equals(events.`$group_0`, events__group_0.key) + WHERE and(equals(events.team_id, 2), ifNull(equals(events__group_0.properties___industry, 'finance'), 0), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_groups_filtering_person_on_events.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + events.person_id AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS events__group_0 ON equals(events.`$group_0`, events__group_0.key) + WHERE and(equals(events.team_id, 2), ifNull(equals(events__group_0.properties___industry, 'technology'), 0), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY events.person_id ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_groups_filtering_person_on_events.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + events.person_id AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 1)) + GROUP BY groups.group_type_index, + groups.group_key) AS events__group_1 ON equals(events.`$group_1`, events__group_1.key) + WHERE and(equals(events.team_id, 2), ifNull(equals(events__group_1.properties___industry, 'technology'), 0), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY events.person_id ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_step two'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_step two'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_step two'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_step two'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.2 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_step two'), 0), 1) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_step two'), 0), 1) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.3 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_step three'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_step three'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.4 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '3_step three'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '3_step three'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.5 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_step three'), 0), 1) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_step three'), 0), 1) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.6 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '4_step four'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '4_step four'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.7 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '4_step four'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '4_step four'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_dropoffs.8 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '4_step four'), 0), 1) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '4_step four'), 0), 1) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_person_on_events_v2 + ''' + + SELECT DISTINCT person_id + FROM events + WHERE team_id = 2 + AND distinct_id = 'poev2_p2' + ''' +# --- +# name: ClickhousePathsUDF.test_person_on_events_v2.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_recording + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s3', 's1', 's5'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_for_dropoff + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_/2'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_/2'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_for_dropoff.1 + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_/3'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_/3'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_for_dropoff.2 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s1'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_with_no_window_or_session_id + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_with_no_window_or_session_id.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_with_start_and_end + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/3') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/1') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/3') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/3') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/1') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/3') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_recording_with_start_and_end.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s1'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_respect_session_limits + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/5') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end.3 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/2') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end_materialized + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end_materialized.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/5') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end_materialized.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_start_and_end_materialized.3 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/2') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_start_dropping_orphaned_edges + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/2') AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 6 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_step_conversion_times + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 2) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 2) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 2) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 2) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 2) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 2) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 2) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 2) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 2) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 2) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 2) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 2) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.2 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 2) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 2) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 2) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 2) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 2) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 2) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 2) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 2) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 2) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 2) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.3 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 3) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 3) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.4 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 3) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 3) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 3) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 3) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 3) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 3) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 3) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 3) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 3) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 3) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 3) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 3) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.5 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.6 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 4) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 4) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 4) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 4) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 4) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 4) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 4) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 4) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.7 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 4) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 4) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 4) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 4) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 4) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 4) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 4) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 4) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_step_limit.8 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 4) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 4) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 4) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_/3'), 0), ifNull(equals(path_key, '4_/4'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 4) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 4) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 4) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 4) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 4) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_/3'), 0), ifNull(equals(path_key, '4_/4'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: ClickhousePathsUDF.test_wildcard_groups_across_people + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['/bar/*/foo'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['/bar/.*/foo']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: ClickhousePathsUDF.test_wildcard_groups_evil_input + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['(a+)+', + '[aaa|aaaa]+', + '1.*', + '.*', + '/3?q=1', + '/3*'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['\\(a\\+\\)\\+', '\\[aaa\\|aaaa\\]\\+', '1\\..*', '\\..*', '/3\\?q=1', '/3.*']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- # name: TestClickhousePaths.test_end ''' SELECT last_path_key AS source_event, @@ -82,7 +6009,5934 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_end.1 +# name: TestClickhousePaths.test_end.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_end_materialized + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), nullIf(nullIf(events.`mat_$screen_name`, ''), 'null'), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_end_materialized.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), nullIf(nullIf(events.`mat_$screen_name`, ''), 'null'), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_exclusion_filters_with_wildcard_groups + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['/bar/*/foo'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['/bar/.*/foo']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), and(equals(events.event, '$pageview'), ifNull(notIn(path_item, ['/bar/*/foo']), 0))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_exclusion_filters_with_wildcard_groups.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['/xxx/invalid/*'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['/xxx/invalid/.*']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), and(equals(events.event, '$pageview'), ifNull(notIn(path_item, ['/bar/*/foo']), 0))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_inclusion_exclusion_filters + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_inclusion_exclusion_filters.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$screen')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_inclusion_exclusion_filters.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_inclusion_exclusion_filters.3 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), and(or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$'))), ifNull(notIn(path_item, ['/custom1', '/1', '/2', '/3']), 0))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_event_ordering + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-03 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_groups_filtering_person_on_events + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS events__group_0 ON equals(events.`$group_0`, events__group_0.key) + WHERE and(equals(events.team_id, 2), ifNull(equals(events__group_0.properties___industry, 'finance'), 0), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_groups_filtering_person_on_events.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + events.person_id AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 0)) + GROUP BY groups.group_type_index, + groups.group_key) AS events__group_0 ON equals(events.`$group_0`, events__group_0.key) + WHERE and(equals(events.team_id, 2), ifNull(equals(events__group_0.properties___industry, 'technology'), 0), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY events.person_id ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_groups_filtering_person_on_events.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + events.person_id AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT JOIN + (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), toTimeZone(groups._timestamp, 'UTC')) AS properties___industry, + groups.group_type_index AS index, + groups.group_key AS key + FROM groups + WHERE and(equals(groups.team_id, 2), equals(index, 1)) + GROUP BY groups.group_type_index, + groups.group_key) AS events__group_1 ON equals(events.`$group_1`, events__group_1.key) + WHERE and(equals(events.team_id, 2), ifNull(equals(events__group_1.properties___industry, 'technology'), 0), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY events.person_id ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_step two'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_step two'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_step two'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_step two'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.2 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_step two'), 0), 1) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_step two'), 0), 1) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.3 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_step three'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_step three'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.4 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '3_step three'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '3_step three'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.5 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_step three'), 0), 1) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_step three'), 0), 1) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.6 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '4_step four'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '4_step four'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.7 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '4_step four'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '4_step four'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_dropoffs.8 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(events.event, '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '4_step four'), 0), 1) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(events.event, '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), not(startsWith(events.event, '$'))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '4_step four'), 0), 1) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_person_on_events_v2 + ''' + + SELECT DISTINCT person_id + FROM events + WHERE team_id = 2 + AND distinct_id = 'poev2_p2' + ''' +# --- +# name: TestClickhousePaths.test_person_on_events_v2.1 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-02-01 23:59:59', 6, 'UTC')))), or(equals(events.event, '$pageview'), equals(events.event, '$screen'), not(startsWith(events.event, '$')))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_recording + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s3', 's1', 's5'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_for_dropoff + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_/2'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '2_/2'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_for_dropoff.1 + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_/3'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(path_dropoff_key, '3_/3'), 0), ifNull(equals(path_dropoff_key, path_key), isNull(path_dropoff_key) + and isNull(path_key))) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_for_dropoff.2 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s1'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_with_no_window_or_session_id + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 5) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 5) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 5) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 5) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 5) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 5) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 5) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 5) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 5) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_with_no_window_or_session_id.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_with_start_and_end + ''' + SELECT persons.id AS id, + persons.created_at AS created_at, + source.event_count AS event_count, + source.matching_events AS matching_events + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/3') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/1') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/3') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source + INNER JOIN + (SELECT argMax(toTimeZone(person.created_at, 'UTC'), person.version) AS created_at, + person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/3') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/1') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/3') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-02 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE ifNull(equals(path_key, '2_/2'), 0) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_recording_with_start_and_end.1 + ''' + SELECT DISTINCT session_replay_events.session_id AS session_id + FROM session_replay_events + WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2012-01-01 03:21:34.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, ['s1'])) + LIMIT 100 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_respect_session_limits + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/5') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end.3 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/2') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end_materialized + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end_materialized.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/5') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/5') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 5), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(5, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 5), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(5, 2)), [filtered_timings[plus(1, intDiv(5, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 5), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(5, 2)), [filtered_uuid[plus(1, intDiv(5, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 5), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(5, 2)), [filtered_timestamp[plus(1, intDiv(5, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 5), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(5, 2)), [filtered_session_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 5), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(5, 2)), [filtered_window_id[plus(1, intDiv(5, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(5, 2)), intDiv(5, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '1_/5'), 0), ifNull(equals(path_key, '2_/about'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end_materialized.2 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_start_and_end_materialized.3 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + indexOf(compact_path, '/2') AS start_target_index, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, + indexOf(start_filtered_path, '/about') AS end_target_index, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, + if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, + if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, + if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, + if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, + if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, + if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, + if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, + if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, '/about') AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, indexOf(compact_path, '/2') AS start_target_index, if(ifNull(greater(start_target_index, 0), 0), arraySlice(compact_path, start_target_index), compact_path) AS start_filtered_path, indexOf(start_filtered_path, '/about') AS end_target_index, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_path, end_target_index), start_filtered_path) AS filtered_path, if(ifNull(greater(length(filtered_path), 4), 0), arrayConcat(arraySlice(filtered_path, 1, intDiv(4, 2)), ['...'], arraySlice(filtered_path, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_path) AS limited_path, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timings, start_target_index), timings) AS start_filtered_timings, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timings, end_target_index), start_filtered_timings) AS filtered_timings, if(ifNull(greater(length(filtered_timings), 4), 0), arrayConcat(arraySlice(filtered_timings, 1, intDiv(4, 2)), [filtered_timings[plus(1, intDiv(4, 2))]], arraySlice(filtered_timings, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timings) AS limited_timings, if(ifNull(greater(start_target_index, 0), 0), arraySlice(uuid, start_target_index), uuid) AS start_filtered_uuid, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_uuid, end_target_index), start_filtered_uuid) AS filtered_uuid, if(ifNull(greater(length(filtered_uuid), 4), 0), arrayConcat(arraySlice(filtered_uuid, 1, intDiv(4, 2)), [filtered_uuid[plus(1, intDiv(4, 2))]], arraySlice(filtered_uuid, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_uuid) AS limited_uuid, if(ifNull(greater(start_target_index, 0), 0), arraySlice(timestamp, start_target_index), timestamp) AS start_filtered_timestamp, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_timestamp, end_target_index), start_filtered_timestamp) AS filtered_timestamp, if(ifNull(greater(length(filtered_timestamp), 4), 0), arrayConcat(arraySlice(filtered_timestamp, 1, intDiv(4, 2)), [filtered_timestamp[plus(1, intDiv(4, 2))]], arraySlice(filtered_timestamp, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_timestamp) AS limited_timestamp, if(ifNull(greater(start_target_index, 0), 0), arraySlice(session_id, start_target_index), session_id) AS start_filtered_session_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_session_id, end_target_index), start_filtered_session_id) AS filtered_session_id, if(ifNull(greater(length(filtered_session_id), 4), 0), arrayConcat(arraySlice(filtered_session_id, 1, intDiv(4, 2)), [filtered_session_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_session_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_session_id) AS limited_session_id, if(ifNull(greater(start_target_index, 0), 0), arraySlice(window_id, start_target_index), window_id) AS start_filtered_window_id, if(ifNull(greater(end_target_index, 0), 0), arrayResize(start_filtered_window_id, end_target_index), start_filtered_window_id) AS filtered_window_id, if(ifNull(greater(length(filtered_window_id), 4), 0), arrayConcat(arraySlice(filtered_window_id, 1, intDiv(4, 2)), [filtered_window_id[plus(1, intDiv(4, 2))]], arraySlice(filtered_window_id, multiply(-1, intDiv(4, 2)), intDiv(4, 2))), filtered_window_id) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(nullIf(nullIf(events.`mat_$current_url`, ''), 'null'), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE and(ifNull(greater(start_target_index, 0), 0), ifNull(greater(end_target_index, 0), 0)))) + WHERE and(ifNull(equals(last_path_key, '3_...'), 0), ifNull(equals(path_key, '4_/5'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_start_dropping_orphaned_edges + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/2') AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 6 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_step_conversion_times + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_step_limit + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 2) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 2) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.1 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 2) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 2) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 2) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 2) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 2) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 2) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 2) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 2) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 2) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 2) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.2 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 2) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 2) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 2) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 2) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 2) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 2) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 2) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 2) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 2) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 2) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 2) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.3 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 3) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 3) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.4 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 3) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 3) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 3) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 3) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 3) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 3) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 3) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 3) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 3) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 3) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 3) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 3) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.5 + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.6 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 4) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 4) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 4) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 4) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 4) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 4) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 4) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 4) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '1_/1'), 0), ifNull(equals(path_key, '2_/2'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.7 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 4) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 4) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 4) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 4) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 4) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 4) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 4) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 4) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '2_/2'), 0), ifNull(equals(path_key, '3_/3'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_step_limit.8 + ''' + SELECT persons.id AS id + FROM + (SELECT person_id AS actor_id, + groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, + count(*) AS event_count + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key, + final_uuid AS uuid, + final_timestamp AS timestamp, + final_session_id AS session_id, + final_window_id AS window_id + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + joined_path_tuple.4 AS final_uuid, + joined_path_tuple.5 AS final_timestamp, + joined_path_tuple.6 AS final_session_id, + joined_path_tuple.7 AS final_window_id, + arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, + arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, + arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, + arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, + arraySlice(filtered_uuid, 1, 4) AS limited_uuid, + if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, + arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, + if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, + arraySlice(filtered_session_id, 1, 4) AS limited_session_id, + if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, + arraySlice(filtered_window_id, 1, 4) AS limited_window_id, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, + path_time_tuple.4 AS uuid_items, + path_time_tuple.5 AS timestamp_items, + path_time_tuple.6 AS session_id_items, + path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list, + groupArray(uuid) AS uuid_list, + groupArray(timestamp) AS timestamp_list, + groupArray(session_id) AS session_id_list, + groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + events.uuid AS uuid, + toTimeZone(events.timestamp, 'UTC') AS timestamp, + ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, + ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_/3'), 0), ifNull(equals(path_key, '4_/4'), 0)) + GROUP BY person_id) AS source + INNER JOIN + (SELECT person.id AS id + FROM person + WHERE and(equals(person.team_id, 2), in(id, + (SELECT source.actor_id AS actor_id + FROM + (SELECT person_id AS actor_id, groupUniqArray(100)(tuple(timestamp, uuid, session_id, window_id)) AS matching_events, count(*) AS event_count + FROM + (SELECT person_id AS person_id, path AS path, conversion_time AS conversion_time, event_in_session_index AS event_in_session_index, concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, path_dropoff_key AS path_dropoff_key, final_uuid AS uuid, final_timestamp AS timestamp, final_session_id AS session_id, final_window_id AS window_id + FROM + (SELECT person_id AS person_id, joined_path_tuple.1 AS path, joined_path_tuple.2 AS conversion_time, joined_path_tuple.3 AS prev_path, event_in_session_index, session_index AS session_index, arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, arrayFilter((x, y) -> y, time, mapping) AS timings, arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, indexOf(compact_path, NULL) AS target_index, joined_path_tuple.4 AS final_uuid, joined_path_tuple.5 AS final_timestamp, joined_path_tuple.6 AS final_session_id, joined_path_tuple.7 AS final_window_id, arrayFilter((x, y) -> y, uuid_items, mapping) AS uuid, arrayFilter((x, y) -> y, timestamp_items, mapping) AS timestamp, arrayFilter((x, y) -> y, session_id_items, mapping) AS session_id, arrayFilter((x, y) -> y, window_id_items, mapping) AS window_id, if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, arraySlice(filtered_path, 1, 4) AS limited_path, if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, arraySlice(filtered_timings, 1, 4) AS limited_timings, if(ifNull(greater(target_index, 0), 0), arraySlice(uuid, target_index), uuid) AS filtered_uuid, arraySlice(filtered_uuid, 1, 4) AS limited_uuid, if(ifNull(greater(target_index, 0), 0), arraySlice(timestamp, target_index), timestamp) AS filtered_timestamp, arraySlice(filtered_timestamp, 1, 4) AS limited_timestamp, if(ifNull(greater(target_index, 0), 0), arraySlice(session_id, target_index), session_id) AS filtered_session_id, arraySlice(filtered_session_id, 1, 4) AS limited_session_id, if(ifNull(greater(target_index, 0), 0), arraySlice(window_id, target_index), window_id) AS filtered_window_id, arraySlice(filtered_window_id, 1, 4) AS limited_window_id, arrayDifference(limited_timings) AS timings_diff, concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, '')), limited_uuid, limited_timestamp, limited_session_id, limited_window_id) AS limited_path_timings + FROM + (SELECT person_id AS person_id, path_time_tuple.1 AS path_basic, path_time_tuple.2 AS time, session_index, arrayZip(path_list, timing_list, arrayDifference(timing_list), uuid_list, timestamp_list, session_id_list, window_id_list) AS paths_tuple, arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths, path_time_tuple.4 AS uuid_items, path_time_tuple.5 AS timestamp_items, path_time_tuple.6 AS session_id_items, path_time_tuple.7 AS window_id_items + FROM + (SELECT person_id AS person_id, groupArray(timestamp) AS timing_list, groupArray(path_item) AS path_list, groupArray(uuid) AS uuid_list, groupArray(timestamp) AS timestamp_list, groupArray(session_id) AS session_id_list, groupArray(window_id) AS window_id_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, events.uuid AS uuid, toTimeZone(events.timestamp, 'UTC') AS timestamp, ifNull(nullIf(nullIf(events.`$session_id`, ''), 'null'), '') AS session_id, ifNull(nullIf(nullIf(events.`$window_id`, ''), 'null'), '') AS window_id, NULL AS groupings, multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2011-12-31 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE and(ifNull(equals(last_path_key, '3_/3'), 0), ifNull(equals(path_key, '4_/4'), 0)) + GROUP BY person_id) AS source))) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(toTimeZone(person.created_at, 'UTC'), person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 0)) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, source.actor_id) + ORDER BY persons.id ASC + LIMIT 101 + OFFSET 0 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 + ''' +# --- +# name: TestClickhousePaths.test_wildcard_groups_across_people + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 4) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 4) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['/bar/*/foo'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['/bar/.*/foo']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePaths.test_wildcard_groups_evil_input + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, NULL) AS target_index, + if(ifNull(greater(target_index, 0), 0), arraySlice(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, 1, 5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arraySlice(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, 1, 5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event), '') AS path_item_ungrouped, + ['(a+)+', + '[aaa|aaaa]+', + '1.*', + '.*', + '/3?q=1', + '/3*'] AS groupings, + multiMatchAnyIndex(path_item_ungrouped, ['\\(a\\+\\)\\+', '\\[aaa\\|aaaa\\]\\+', '1\\..*', '\\..*', '/3\\?q=1', '/3.*']) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2012-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-05-23 23:59:59', 6, 'UTC')))), equals(events.event, '$pageview')) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index)) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePathsUDF.test_end + ''' + SELECT last_path_key AS source_event, + path_key AS target_event, + count(*) AS event_count, + avg(conversion_time) AS average_conversion_time + FROM + (SELECT person_id AS person_id, + path AS path, + conversion_time AS conversion_time, + event_in_session_index AS event_in_session_index, + concat(ifNull(toString(event_in_session_index), ''), '_', ifNull(toString(path), '')) AS path_key, + if(ifNull(greater(event_in_session_index, 1), 0), concat(ifNull(toString(minus(event_in_session_index, 1)), ''), '_', ifNull(toString(prev_path), '')), NULL) AS last_path_key, + path_dropoff_key AS path_dropoff_key + FROM + (SELECT person_id AS person_id, + joined_path_tuple.1 AS path, + joined_path_tuple.2 AS conversion_time, + joined_path_tuple.3 AS prev_path, + event_in_session_index, + session_index AS session_index, + arrayPopFront(arrayPushBack(path_basic, '')) AS path_basic_0, + arrayMap((x, y) -> if(ifNull(equals(x, y), isNull(x) + and isNull(y)), 0, 1), path_basic, path_basic_0) AS mapping, + arrayFilter((x, y) -> y, time, mapping) AS timings, + arrayFilter((x, y) -> y, path_basic, mapping) AS compact_path, + indexOf(compact_path, '/about') AS target_index, + if(ifNull(greater(target_index, 0), 0), arrayResize(compact_path, target_index), compact_path) AS filtered_path, + arraySlice(filtered_path, -5) AS limited_path, + if(ifNull(greater(target_index, 0), 0), arrayResize(timings, target_index), timings) AS filtered_timings, + arraySlice(filtered_timings, -5) AS limited_timings, + arrayDifference(limited_timings) AS timings_diff, + concat(ifNull(toString(length(limited_path)), ''), '_', ifNull(toString(limited_path[-1]), '')) AS path_dropoff_key, + arrayZip(limited_path, timings_diff, arrayPopBack(arrayPushFront(limited_path, ''))) AS limited_path_timings + FROM + (SELECT person_id AS person_id, + path_time_tuple.1 AS path_basic, + path_time_tuple.2 AS time, + session_index, + arrayZip(path_list, timing_list, arrayDifference(timing_list)) AS paths_tuple, + arraySplit(x -> if(ifNull(less(x.3, 1800), 0), 0, 1), paths_tuple) AS session_paths + FROM + (SELECT person_id AS person_id, + groupArray(timestamp) AS timing_list, + groupArray(path_item) AS path_list + FROM + (SELECT toTimeZone(events.timestamp, 'UTC') AS timestamp, + if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS person_id, + ifNull(if(equals(events.event, '$screen'), replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$screen_name'), ''), 'null'), '^"|"$', ''), if(equals(events.event, '$pageview'), replaceRegexpAll(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(events.properties, '$current_url'), ''), 'null'), '^"|"$', ''), ''), '(.)/$', '\\1'), events.event)), '') AS path_item_ungrouped, + NULL AS groupings, + multiMatchAnyIndex(path_item_ungrouped, NULL) AS group_index, + (if(ifNull(greater(group_index, 0), 0), groupings[group_index], path_item_ungrouped) AS path_item) AS path_item + FROM events + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__override ON equals(events.distinct_id, events__override.distinct_id) + WHERE and(equals(events.team_id, 2), and(greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2021-05-07 23:59:59', 6, 'UTC'))))) + ORDER BY if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) ASC, toTimeZone(events.timestamp, 'UTC') ASC) + GROUP BY person_id) ARRAY + JOIN session_paths AS path_time_tuple, + arrayEnumerate(session_paths) AS session_index) ARRAY + JOIN limited_path_timings AS joined_path_tuple, + arrayEnumerate(limited_path_timings) AS event_in_session_index + WHERE ifNull(greater(target_index, 0), 0))) + WHERE isNotNull(source_event) + GROUP BY source_event, + target_event + ORDER BY event_count DESC, + source_event ASC, + target_event ASC + LIMIT 50 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=23622320128 + ''' +# --- +# name: TestClickhousePathsUDF.test_end.1 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -165,7 +12019,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_end_materialized +# name: TestClickhousePathsUDF.test_end_materialized ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -248,7 +12102,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_end_materialized.1 +# name: TestClickhousePathsUDF.test_end_materialized.1 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -331,7 +12185,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_exclusion_filters_with_wildcard_groups +# name: TestClickhousePathsUDF.test_event_exclusion_filters_with_wildcard_groups ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -413,7 +12267,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_exclusion_filters_with_wildcard_groups.1 +# name: TestClickhousePathsUDF.test_event_exclusion_filters_with_wildcard_groups.1 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -495,7 +12349,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_inclusion_exclusion_filters +# name: TestClickhousePathsUDF.test_event_inclusion_exclusion_filters ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -577,7 +12431,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_inclusion_exclusion_filters.1 +# name: TestClickhousePathsUDF.test_event_inclusion_exclusion_filters.1 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -659,7 +12513,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_inclusion_exclusion_filters.2 +# name: TestClickhousePathsUDF.test_event_inclusion_exclusion_filters.2 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -741,7 +12595,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_inclusion_exclusion_filters.3 +# name: TestClickhousePathsUDF.test_event_inclusion_exclusion_filters.3 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -823,7 +12677,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_event_ordering +# name: TestClickhousePathsUDF.test_event_ordering ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -905,7 +12759,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_groups_filtering_person_on_events +# name: TestClickhousePathsUDF.test_groups_filtering_person_on_events ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -995,7 +12849,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_groups_filtering_person_on_events.1 +# name: TestClickhousePathsUDF.test_groups_filtering_person_on_events.1 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -1078,7 +12932,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_groups_filtering_person_on_events.2 +# name: TestClickhousePathsUDF.test_groups_filtering_person_on_events.2 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -1161,7 +13015,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs +# name: TestClickhousePathsUDF.test_person_dropoffs ''' SELECT persons.id AS id FROM @@ -1310,7 +13164,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.1 +# name: TestClickhousePathsUDF.test_person_dropoffs.1 ''' SELECT persons.id AS id FROM @@ -1457,7 +13311,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.2 +# name: TestClickhousePathsUDF.test_person_dropoffs.2 ''' SELECT persons.id AS id FROM @@ -1604,7 +13458,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.3 +# name: TestClickhousePathsUDF.test_person_dropoffs.3 ''' SELECT persons.id AS id FROM @@ -1753,7 +13607,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.4 +# name: TestClickhousePathsUDF.test_person_dropoffs.4 ''' SELECT persons.id AS id FROM @@ -1900,7 +13754,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.5 +# name: TestClickhousePathsUDF.test_person_dropoffs.5 ''' SELECT persons.id AS id FROM @@ -2047,7 +13901,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.6 +# name: TestClickhousePathsUDF.test_person_dropoffs.6 ''' SELECT persons.id AS id FROM @@ -2196,7 +14050,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.7 +# name: TestClickhousePathsUDF.test_person_dropoffs.7 ''' SELECT persons.id AS id FROM @@ -2343,7 +14197,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_dropoffs.8 +# name: TestClickhousePathsUDF.test_person_dropoffs.8 ''' SELECT persons.id AS id FROM @@ -2490,7 +14344,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_person_on_events_v2 +# name: TestClickhousePathsUDF.test_person_on_events_v2 ''' SELECT DISTINCT person_id @@ -2499,7 +14353,7 @@ AND distinct_id = 'poev2_p2' ''' # --- -# name: TestClickhousePaths.test_person_on_events_v2.1 +# name: TestClickhousePathsUDF.test_person_on_events_v2.1 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -2581,7 +14435,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_recording +# name: TestClickhousePathsUDF.test_recording ''' SELECT persons.id AS id, persons.created_at AS created_at, @@ -2732,7 +14586,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording.1 +# name: TestClickhousePathsUDF.test_recording.1 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -2746,7 +14600,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_for_dropoff +# name: TestClickhousePathsUDF.test_recording_for_dropoff ''' SELECT persons.id AS id, persons.created_at AS created_at, @@ -2899,7 +14753,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_for_dropoff.1 +# name: TestClickhousePathsUDF.test_recording_for_dropoff.1 ''' SELECT persons.id AS id, persons.created_at AS created_at, @@ -3052,7 +14906,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_for_dropoff.2 +# name: TestClickhousePathsUDF.test_recording_for_dropoff.2 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -3066,7 +14920,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_with_no_window_or_session_id +# name: TestClickhousePathsUDF.test_recording_with_no_window_or_session_id ''' SELECT persons.id AS id, persons.created_at AS created_at, @@ -3217,7 +15071,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_with_no_window_or_session_id.1 +# name: TestClickhousePathsUDF.test_recording_with_no_window_or_session_id.1 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -3231,7 +15085,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_with_start_and_end +# name: TestClickhousePathsUDF.test_recording_with_start_and_end ''' SELECT persons.id AS id, persons.created_at AS created_at, @@ -3392,7 +15246,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_recording_with_start_and_end.1 +# name: TestClickhousePathsUDF.test_recording_with_start_and_end.1 ''' SELECT DISTINCT session_replay_events.session_id AS session_id FROM session_replay_events @@ -3406,7 +15260,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_respect_session_limits +# name: TestClickhousePathsUDF.test_respect_session_limits ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -3488,7 +15342,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_start_and_end +# name: TestClickhousePathsUDF.test_start_and_end ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -3575,7 +15429,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_start_and_end.1 +# name: TestClickhousePathsUDF.test_start_and_end.1 ''' SELECT persons.id AS id FROM @@ -3732,7 +15586,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_start_and_end.2 +# name: TestClickhousePathsUDF.test_start_and_end.2 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -3819,7 +15673,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_start_and_end.3 +# name: TestClickhousePathsUDF.test_start_and_end.3 ''' SELECT persons.id AS id FROM @@ -3976,7 +15830,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_start_and_end_materialized +# name: TestClickhousePathsUDF.test_start_and_end_materialized ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -4063,7 +15917,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_start_and_end_materialized.1 +# name: TestClickhousePathsUDF.test_start_and_end_materialized.1 ''' SELECT persons.id AS id FROM @@ -4220,7 +16074,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_start_and_end_materialized.2 +# name: TestClickhousePathsUDF.test_start_and_end_materialized.2 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -4307,7 +16161,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_start_and_end_materialized.3 +# name: TestClickhousePathsUDF.test_start_and_end_materialized.3 ''' SELECT persons.id AS id FROM @@ -4464,7 +16318,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_start_dropping_orphaned_edges +# name: TestClickhousePathsUDF.test_start_dropping_orphaned_edges ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -4547,7 +16401,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_step_conversion_times +# name: TestClickhousePathsUDF.test_step_conversion_times ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -4629,7 +16483,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_step_limit +# name: TestClickhousePathsUDF.test_step_limit ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -4711,7 +16565,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_step_limit.1 +# name: TestClickhousePathsUDF.test_step_limit.1 ''' SELECT persons.id AS id FROM @@ -4858,7 +16712,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_step_limit.2 +# name: TestClickhousePathsUDF.test_step_limit.2 ''' SELECT persons.id AS id FROM @@ -5005,7 +16859,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_step_limit.3 +# name: TestClickhousePathsUDF.test_step_limit.3 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -5087,7 +16941,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_step_limit.4 +# name: TestClickhousePathsUDF.test_step_limit.4 ''' SELECT persons.id AS id FROM @@ -5234,7 +17088,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_step_limit.5 +# name: TestClickhousePathsUDF.test_step_limit.5 ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -5316,7 +17170,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_step_limit.6 +# name: TestClickhousePathsUDF.test_step_limit.6 ''' SELECT persons.id AS id FROM @@ -5463,7 +17317,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_step_limit.7 +# name: TestClickhousePathsUDF.test_step_limit.7 ''' SELECT persons.id AS id FROM @@ -5610,7 +17464,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_step_limit.8 +# name: TestClickhousePathsUDF.test_step_limit.8 ''' SELECT persons.id AS id FROM @@ -5757,7 +17611,7 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestClickhousePaths.test_wildcard_groups_across_people +# name: TestClickhousePathsUDF.test_wildcard_groups_across_people ''' SELECT last_path_key AS source_event, path_key AS target_event, @@ -5839,7 +17693,7 @@ max_bytes_before_external_group_by=23622320128 ''' # --- -# name: TestClickhousePaths.test_wildcard_groups_evil_input +# name: TestClickhousePathsUDF.test_wildcard_groups_evil_input ''' SELECT last_path_key AS source_event, path_key AS target_event, diff --git a/posthog/hogql_queries/insights/test/test_paths_query_runner_ee.py b/posthog/hogql_queries/insights/test/test_paths_query_runner_ee.py index 4b593c75e8e6d..a00ae50de973e 100644 --- a/posthog/hogql_queries/insights/test/test_paths_query_runner_ee.py +++ b/posthog/hogql_queries/insights/test/test_paths_query_runner_ee.py @@ -1,7 +1,7 @@ from datetime import timedelta from typing import Any from unittest import skip -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch, Mock from uuid import UUID from django.test import TestCase @@ -40,7 +40,8 @@ ONE_MINUTE = 60_000 # 1 minute in milliseconds -class TestClickhousePaths(ClickhouseTestMixin, APIBaseTest): +class BaseTestClickhousePaths(ClickhouseTestMixin, APIBaseTest): + __test__ = False maxDiff = None def _create_groups(self): @@ -4721,6 +4722,18 @@ def test_wildcard_groups_with_sampling(self): ) +insight_funnels_use_udf_funnel_flag_side_effect = lambda key, *args, **kwargs: key == "insight-funnels-use-udf" + + +class ClickhousePathsUDF(BaseTestClickhousePaths): + __test__ = True + + +@patch("posthoganalytics.feature_enabled", new=Mock(side_effect=insight_funnels_use_udf_funnel_flag_side_effect)) +class TestClickhousePathsUDF(BaseTestClickhousePaths): + __test__ = True + + class TestClickhousePathsEdgeValidation(TestCase): BASIC_PATH = [("1_a", "2_b"), ("2_b", "3_c"), ("3_c", "4_d")] # a->b->c->d BASIC_PATH_2 = [("1_x", "2_y"), ("2_y", "3_z")] # x->y->z diff --git a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr index 35a6ce39c4b15..ed0ddee0e0f34 100644 --- a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr +++ b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr @@ -851,14 +851,49 @@ # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.1 ''' - /* celery:posthog.tasks.tasks.sync_insight_caching_state */ - SELECT team_id, - date_diff('second', max(timestamp), now()) AS age - FROM events - WHERE timestamp > date_sub(DAY, 3, now()) - AND timestamp < now() - GROUP BY team_id - ORDER BY age; + SELECT groupArray(1)(date)[1] AS date, + arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 25), 0), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + FROM + (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, + arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) + and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, + breakdown_value AS breakdown_value, + rowNumberInAllBlocks() AS row_number + FROM + (SELECT sum(total) AS count, + day_start AS day_start, + breakdown_value AS breakdown_value + FROM + (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, + toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value + FROM events AS e SAMPLE 1.0 + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up')) + GROUP BY day_start, + breakdown_value) + GROUP BY day_start, + breakdown_value + ORDER BY day_start ASC, breakdown_value ASC) + GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) + GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC + LIMIT 50000 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 ''' # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.10 @@ -1075,38 +1110,143 @@ # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.2 ''' - /* celery:posthog.tasks.tasks.sync_insight_caching_state */ - SELECT team_id, - date_diff('second', max(timestamp), now()) AS age - FROM events - WHERE timestamp > date_sub(DAY, 3, now()) - AND timestamp < now() - GROUP BY team_id - ORDER BY age; + SELECT groupArray(1)(date)[1] AS date, + arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 25), 0), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + FROM + (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, + arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) + and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, + breakdown_value AS breakdown_value, + rowNumberInAllBlocks() AS row_number + FROM + (SELECT sum(total) AS count, + day_start AS day_start, + breakdown_value AS breakdown_value + FROM + (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, + toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value + FROM events AS e SAMPLE 1.0 + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up')) + GROUP BY day_start, + breakdown_value) + GROUP BY day_start, + breakdown_value + ORDER BY day_start ASC, breakdown_value ASC) + GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) + GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC + LIMIT 50000 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 ''' # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.3 ''' - /* celery:posthog.tasks.tasks.sync_insight_caching_state */ - SELECT team_id, - date_diff('second', max(timestamp), now()) AS age - FROM events - WHERE timestamp > date_sub(DAY, 3, now()) - AND timestamp < now() - GROUP BY team_id - ORDER BY age; + SELECT groupArray(1)(date)[1] AS date, + arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, + arrayMap(i -> if(ifNull(ifNull(greaterOrEquals(row_number, 25), 0), 0), '$$_posthog_breakdown_other_$$', i), breakdown_value) AS breakdown_value + FROM + (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, + arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) + and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, + breakdown_value AS breakdown_value, + rowNumberInAllBlocks() AS row_number + FROM + (SELECT sum(total) AS count, + day_start AS day_start, + [ifNull(toString(breakdown_value_1), '$$_posthog_breakdown_null_$$')] AS breakdown_value + FROM + (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, + toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value_1 + FROM events AS e SAMPLE 1.0 + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up')) + GROUP BY day_start, + breakdown_value_1) + GROUP BY day_start, + breakdown_value_1 + ORDER BY day_start ASC, breakdown_value ASC) + GROUP BY breakdown_value + ORDER BY if(has(breakdown_value, '$$_posthog_breakdown_other_$$'), 2, if(has(breakdown_value, '$$_posthog_breakdown_null_$$'), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC) + WHERE arrayExists(x -> isNotNull(x), breakdown_value) + GROUP BY breakdown_value + ORDER BY if(has(breakdown_value, '$$_posthog_breakdown_other_$$'), 2, if(has(breakdown_value, '$$_posthog_breakdown_null_$$'), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC + LIMIT 50000 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 ''' # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.4 ''' - /* celery:posthog.tasks.tasks.sync_insight_caching_state */ - SELECT team_id, - date_diff('second', max(timestamp), now()) AS age - FROM events - WHERE timestamp > date_sub(DAY, 3, now()) - AND timestamp < now() - GROUP BY team_id - ORDER BY age; + SELECT groupArray(1)(date)[1] AS date, + arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, + arrayMap(i -> if(ifNull(ifNull(greaterOrEquals(row_number, 25), 0), 0), '$$_posthog_breakdown_other_$$', i), breakdown_value) AS breakdown_value + FROM + (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, + arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) + and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, + breakdown_value AS breakdown_value, + rowNumberInAllBlocks() AS row_number + FROM + (SELECT sum(total) AS count, + day_start AS day_start, + [ifNull(toString(breakdown_value_1), '$$_posthog_breakdown_null_$$')] AS breakdown_value + FROM + (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, + toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value_1 + FROM events AS e SAMPLE 1.0 + LEFT OUTER JOIN + (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, + person_distinct_id_overrides.distinct_id AS distinct_id + FROM person_distinct_id_overrides + WHERE equals(person_distinct_id_overrides.team_id, 2) + GROUP BY person_distinct_id_overrides.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up')) + GROUP BY day_start, + breakdown_value_1) + GROUP BY day_start, + breakdown_value_1 + ORDER BY day_start ASC, breakdown_value ASC) + GROUP BY breakdown_value + ORDER BY if(has(breakdown_value, '$$_posthog_breakdown_other_$$'), 2, if(has(breakdown_value, '$$_posthog_breakdown_null_$$'), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC) + WHERE arrayExists(x -> isNotNull(x), breakdown_value) + GROUP BY breakdown_value + ORDER BY if(has(breakdown_value, '$$_posthog_breakdown_other_$$'), 2, if(has(breakdown_value, '$$_posthog_breakdown_null_$$'), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC + LIMIT 50000 SETTINGS readonly=2, + max_execution_time=60, + allow_experimental_object_type=1, + format_csv_allow_double_quotes=0, + max_ast_elements=4000000, + max_expanded_ast_elements=4000000, + max_bytes_before_external_group_by=0 ''' # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.5 diff --git a/posthog/test/user_scripts/test_aggregate_funnel.py b/posthog/test/user_scripts/test_aggregate_funnel.py index 2b20929002f83..f1fe254886c49 100644 --- a/posthog/test/user_scripts/test_aggregate_funnel.py +++ b/posthog/test/user_scripts/test_aggregate_funnel.py @@ -1,3 +1,5 @@ +import io +from contextlib import redirect_stdout from typing import Any from posthog.user_scripts.aggregate_funnel import calculate_funnel_from_user_events @@ -5,9 +7,9 @@ def test(): y = [ - [(1577973600.0, "", [1]), (1577980800.0, "", [2]), (1577984400.0, "", [3])], - [(1577880000.0, "", [1]), (1577883600.0, "", [2]), (1577890800.0, "", [3])], - [(1577973600.0, "", [1]), (1577980800.0, "", [2])], + [(1577973600.0, "uuid", "", [1]), (1577980800.0, "uuid", "", [2]), (1577984400.0, "uuid", "", [3])], + [(1577880000.0, "uuid", "", [1]), (1577883600.0, "uuid", "", [2]), (1577890800.0, "uuid", "", [3])], + [(1577973600.0, "uuid", "", [1]), (1577980800.0, "uuid", "", [2])], ] for x in y: @@ -16,4191 +18,4242 @@ def test(): def test2(): a: list[Any] = [ - [(1720051532.484019, [], [1, 2, 3, 4, 5, 6])], - [(1720105713.331995, [], [1, 2, 3, 4, 5, 6])], - [(1720329565.847159, [], [1, 2, 3, 4, 5, 6])], - [ - (1720186008.567886, [], [1, 2, 3, 4, 5, 6]), - (1720326697.522923, [], [1, 2, 3, 4, 5, 6]), - (1720482974.426314, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720327526.250804, [], [1, 2, 3, 4, 5, 6]), (1720497558.23414, [], [1, 2, 3, 4, 5, 6])], - [ - (1719979738.339271, [], [1, 2, 3, 4, 5, 6]), - (1720025384.961105, [], [1, 2, 3, 4, 5, 6]), - (1720504618.55439, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720136408.619257, [], [1, 2, 3, 4, 5, 6]), - (1720136458.666712, [], [1, 2, 3, 4, 5, 6]), - (1720136460.776795, [], [1, 2, 3, 4, 5, 6]), - (1720136463.761667, [], [1, 2, 3, 4, 5, 6]), - (1720136465.813823, [], [1, 2, 3, 4, 5, 6]), - (1720153490.167176, [], [1, 2, 3, 4, 5, 6]), - (1720153611.687424, [], [1, 2, 3, 4, 5, 6]), - (1720153613.813758, [], [1, 2, 3, 4, 5, 6]), - (1720221238.819741, [], [1, 2, 3, 4, 5, 6]), - (1720221389.412602, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720234125.717526, [], [1, 2, 3, 4, 5, 6])], - [ - (1720245095.229565, [], [1, 2, 3, 4, 5, 6]), - (1720396821.910578, [], [1, 2, 3, 4, 5, 6]), - (1720502554.801179, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720237286.585886, [], [1, 2, 3, 4, 5, 6]), (1720492842.0014, [], [1, 2, 3, 4, 5, 6])], - [(1720145259.463577, [], [1, 2, 3, 4, 5, 6])], - [(1720173037.951133, [], [1, 2, 3, 4, 5, 6]), (1720398629.834351, [], [1, 2, 3, 4, 5, 6])], - [(1720576515.470242, [], [1, 2, 3, 4, 5, 6])], - [(1720488634.248776, [], [1, 2, 3, 4, 5, 6])], - [ - (1719966672.507604, [], [1, 2, 3, 4, 5, 6]), - (1720379305.230415, [], [1, 2, 3, 4, 5, 6]), - (1720485725.30467, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720056848.984567, [], [1, 2, 3, 4, 5, 6]), - (1720234634.97164, [], [1, 2, 3, 4, 5, 6]), - (1720326372.083307, [], [1, 2, 3, 4, 5, 6]), - (1720487169.130815, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719979630.05111, [], [1, 2, 3, 4, 5, 6])], - [(1720067082.599895, [], [1, 2, 3, 4, 5, 6])], - [(1720065455.678956, [], [1, 2, 3, 4, 5, 6])], - [(1720141594.235645, [], [1, 2, 3, 4, 5, 6]), (1720479638.868071, [], [1, 2, 3, 4, 5, 6])], - [(1720172558.775714, [], [1, 2, 3, 4, 5, 6]), (1720589944.987293, [], [1, 2, 3, 4, 5, 6])], - [(1720240665.403432, [], [1, 2, 3, 4, 5, 6]), (1720403456.771406, [], [1, 2, 3, 4, 5, 6])], - [ - (1720151433.593775, [], [1, 2, 3, 4, 5, 6]), - (1720397705.729741, [], [1, 2, 3, 4, 5, 6]), - (1720407937.654196, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720063019.413544, [], [1, 2, 3, 4, 5, 6]), - (1720230670.007217, [], [1, 2, 3, 4, 5, 6]), - (1720572529.432945, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720062676.566511, [], [1, 2, 3, 4, 5, 6]), - (1720062768.411832, [], [1, 2, 3, 4, 5, 6]), - (1720062770.476807, [], [1, 2, 3, 4, 5, 6]), - (1720062771.394614, [], [1, 2, 3, 4, 5, 6]), - (1720156065.434007, [], [1, 2, 3, 4, 5, 6]), - (1720156180.339675, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720053274.311851, [], [1, 2, 3, 4, 5, 6]), (1720574916.370766, [], [1, 2, 3, 4, 5, 6])], - [(1720403600.103166, [], [1, 2, 3, 4, 5, 6])], - [(1720070524.509752, [], [1, 2, 3, 4, 5, 6]), (1720330735.128105, [], [1, 2, 3, 4, 5, 6])], - [ - (1719980823.099161, [], [1, 2, 3, 4, 5, 6]), - (1720109783.667678, [], [1, 2, 3, 4, 5, 6]), - (1720488536.75761, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720120539.020908, [], [1, 2, 3, 4, 5, 6]), - (1720235556.263511, [], [1, 2, 3, 4, 5, 6]), - (1720404531.8727, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720461710.602542, [], [1, 2, 3, 4, 5, 6])], - [(1720142147.27027, [], [1, 2, 3, 4, 5, 6]), (1720463509.177443, [], [1, 2, 3, 4, 5, 6])], - [(1720609249.094945, [], [1, 2, 3, 4, 5, 6])], - [ - (1720061653.09558, [], [1, 2, 3, 4, 5, 6]), - (1720331923.364924, [], [1, 2, 3, 4, 5, 6]), - (1720493879.336969, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719981455.944035, [], [1, 2, 3, 4, 5, 6]), - (1719981517.705732, [], [1, 2, 3, 4, 5, 6]), - (1719994503.81365, [], [1, 2, 3, 4, 5, 6]), - (1719994621.6397, [], [1, 2, 3, 4, 5, 6]), - (1719994623.698368, [], [1, 2, 3, 4, 5, 6]), - (1719994627.578717, [], [1, 2, 3, 4, 5, 6]), - (1719994629.663136, [], [1, 2, 3, 4, 5, 6]), - (1719994631.068061, [], [1, 2, 3, 4, 5, 6]), - (1719994633.142381, [], [1, 2, 3, 4, 5, 6]), - (1720027463.767433, [], [1, 2, 3, 4, 5, 6]), - (1720027502.563106, [], [1, 2, 3, 4, 5, 6]), - (1720027504.670674, [], [1, 2, 3, 4, 5, 6]), - (1720057341.723675, [], [1, 2, 3, 4, 5, 6]), - (1720057343.781939, [], [1, 2, 3, 4, 5, 6]), - (1720145087.601179, [], [1, 2, 3, 4, 5, 6]), - (1720145089.680587, [], [1, 2, 3, 4, 5, 6]), - (1720243008.749524, [], [1, 2, 3, 4, 5, 6]), - (1720243068.439551, [], [1, 2, 3, 4, 5, 6]), - (1720318425.097956, [], [1, 2, 3, 4, 5, 6]), - (1720318427.16319, [], [1, 2, 3, 4, 5, 6]), - (1720318432.221956, [], [1, 2, 3, 4, 5, 6]), - (1720318434.329525, [], [1, 2, 3, 4, 5, 6]), - (1720418148.778433, [], [1, 2, 3, 4, 5, 6]), - (1720418150.861104, [], [1, 2, 3, 4, 5, 6]), - (1720488202.399436, [], [1, 2, 3, 4, 5, 6]), - (1720488212.260625, [], [1, 2, 3, 4, 5, 6]), - (1720488214.365566, [], [1, 2, 3, 4, 5, 6]), - (1720572393.815712, [], [1, 2, 3, 4, 5, 6]), - (1720613041.916708, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720057097.342555, [], [1, 2, 3, 4, 5, 6]), - (1720317039.904735, [], [1, 2, 3, 4, 5, 6]), - (1720483178.967836, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720181661.187285, [], [1, 2, 3, 4, 5, 6])], - [(1720199552.174104, [], [1, 2, 3, 4, 5, 6]), (1720568803.062761, [], [1, 2, 3, 4, 5, 6])], - [ - (1720247391.136136, [], [1, 2, 3, 4, 5, 6]), - (1720410696.088339, [], [1, 2, 3, 4, 5, 6]), - (1720599399.171422, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720312357.61565, [], [1, 2, 3, 4, 5, 6])], - [(1720052008.103911, [], [1, 2, 3, 4, 5, 6]), (1720400141.042944, [], [1, 2, 3, 4, 5, 6])], - [(1720210751.331903, [], [1, 2, 3, 4, 5, 6]), (1720503558.839248, [], [1, 2, 3, 4, 5, 6])], - [ - (1720241352.747626, [], [1, 2, 3, 4, 5, 6]), - (1720321677.766712, [], [1, 2, 3, 4, 5, 6]), - (1720409706.122052, [], [1, 2, 3, 4, 5, 6]), - (1720519728.980875, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977467.931514, [], [1, 2, 3, 4, 5, 6]), (1720568695.132969, [], [1, 2, 3, 4, 5, 6])], - [(1720071302.148667, [], [1, 2, 3, 4, 5, 6]), (1720238096.092618, [], [1, 2, 3, 4, 5, 6])], - [(1720057437.769059, [], [1, 2, 3, 4, 5, 6])], - [ - (1720221473.506037, [], [1, 2, 3, 4, 5, 6]), - (1720348129.55283, [], [1, 2, 3, 4, 5, 6]), - (1720482938.000889, [], [1, 2, 3, 4, 5, 6]), - (1720576755.035308, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720235902.362301, [], [1, 2, 3, 4, 5, 6])], - [(1720024782.723245, [], [1, 2, 3, 4, 5, 6])], - [(1720070158.75827, [], [1, 2, 3, 4, 5, 6])], - [ - (1720000651.858702, [], [1, 2, 3, 4, 5, 6]), - (1720244645.395695, [], [1, 2, 3, 4, 5, 6]), - (1720411107.259775, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720191076.938109, [], [1, 2, 3, 4, 5, 6]), - (1720322967.081356, [], [1, 2, 3, 4, 5, 6]), - (1720323158.146239, [], [1, 2, 3, 4, 5, 6]), - (1720323172.234517, [], [1, 2, 3, 4, 5, 6]), - (1720323206.302768, [], [1, 2, 3, 4, 5, 6]), - (1720323313.146535, [], [1, 2, 3, 4, 5, 6]), - (1720323364.511129, [], [1, 2, 3, 4, 5, 6]), - (1720323458.282407, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720065260.493236, [], [1, 2, 3, 4, 5, 6]), - (1720065334.608797, [], [1, 2, 3, 4, 5, 6]), - (1720141650.234015, [], [1, 2, 3, 4, 5, 6]), - (1720141749.547675, [], [1, 2, 3, 4, 5, 6]), - (1720141751.641012, [], [1, 2, 3, 4, 5, 6]), - (1720154278.705276, [], [1, 2, 3, 4, 5, 6]), - (1720154280.760532, [], [1, 2, 3, 4, 5, 6]), - (1720229499.077048, [], [1, 2, 3, 4, 5, 6]), - (1720229572.436301, [], [1, 2, 3, 4, 5, 6]), - (1720259010.216367, [], [1, 2, 3, 4, 5, 6]), - (1720259234.335094, [], [1, 2, 3, 4, 5, 6]), - (1720259236.42606, [], [1, 2, 3, 4, 5, 6]), - (1720318686.64822, [], [1, 2, 3, 4, 5, 6]), - (1720318843.45613, [], [1, 2, 3, 4, 5, 6]), - (1720318845.509738, [], [1, 2, 3, 4, 5, 6]), - (1720363113.918907, [], [1, 2, 3, 4, 5, 6]), - (1720363184.856665, [], [1, 2, 3, 4, 5, 6]), - (1720400947.604003, [], [1, 2, 3, 4, 5, 6]), - (1720400949.633637, [], [1, 2, 3, 4, 5, 6]), - (1720498232.720406, [], [1, 2, 3, 4, 5, 6]), - (1720498253.802808, [], [1, 2, 3, 4, 5, 6]), - (1720498255.908508, [], [1, 2, 3, 4, 5, 6]), - (1720586991.26782, [], [1, 2, 3, 4, 5, 6]), - (1720587059.251675, [], [1, 2, 3, 4, 5, 6]), - (1720587061.383312, [], [1, 2, 3, 4, 5, 6]), - (1720638042.876812, [], [1, 2, 3, 4, 5, 6]), - (1720638133.182092, [], [1, 2, 3, 4, 5, 6]), - (1720638135.286491, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978486.488845, [], [1, 2, 3, 4, 5, 6]), (1720406010.994165, [], [1, 2, 3, 4, 5, 6])], - [(1720062931.526777, [], [1, 2, 3, 4, 5, 6])], - [ - (1720142330.725196, [], [1, 2, 3, 4, 5, 6]), - (1720238332.287607, [], [1, 2, 3, 4, 5, 6]), - (1720404745.279674, [], [1, 2, 3, 4, 5, 6]), - (1720577388.350881, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719973721.653682, [], [1, 2, 3, 4, 5, 6]), - (1720045556.714061, [], [1, 2, 3, 4, 5, 6]), - (1720286335.062706, [], [1, 2, 3, 4, 5, 6]), - (1720408637.593505, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719980831.540691, [], [1, 2, 3, 4, 5, 6]), - (1719980890.3872, [], [1, 2, 3, 4, 5, 6]), - (1719980892.464391, [], [1, 2, 3, 4, 5, 6]), - (1720027957.165729, [], [1, 2, 3, 4, 5, 6]), - (1720027959.212697, [], [1, 2, 3, 4, 5, 6]), - (1720055928.682589, [], [1, 2, 3, 4, 5, 6]), - (1720055930.747743, [], [1, 2, 3, 4, 5, 6]), - (1720138782.333308, [], [1, 2, 3, 4, 5, 6]), - (1720138842.547168, [], [1, 2, 3, 4, 5, 6]), - (1720138844.667335, [], [1, 2, 3, 4, 5, 6]), - (1720138846.225705, [], [1, 2, 3, 4, 5, 6]), - (1720153595.409537, [], [1, 2, 3, 4, 5, 6]), - (1720153694.792152, [], [1, 2, 3, 4, 5, 6]), - (1720222583.234486, [], [1, 2, 3, 4, 5, 6]), - (1720222651.732326, [], [1, 2, 3, 4, 5, 6]), - (1720222653.840022, [], [1, 2, 3, 4, 5, 6]), - (1720231129.338916, [], [1, 2, 3, 4, 5, 6]), - (1720231262.508465, [], [1, 2, 3, 4, 5, 6]), - (1720315761.130281, [], [1, 2, 3, 4, 5, 6]), - (1720315844.746953, [], [1, 2, 3, 4, 5, 6]), - (1720315846.831435, [], [1, 2, 3, 4, 5, 6]), - (1720406873.849957, [], [1, 2, 3, 4, 5, 6]), - (1720406879.412626, [], [1, 2, 3, 4, 5, 6]), - (1720485467.197531, [], [1, 2, 3, 4, 5, 6]), - (1720485486.733099, [], [1, 2, 3, 4, 5, 6]), - (1720485488.847143, [], [1, 2, 3, 4, 5, 6]), - (1720485492.354688, [], [1, 2, 3, 4, 5, 6]), - (1720485494.434006, [], [1, 2, 3, 4, 5, 6]), - (1720581292.87898, [], [1, 2, 3, 4, 5, 6]), - (1720581372.990683, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965396.997192, [], [1, 2, 3, 4, 5, 6]), - (1720109840.37035, [], [1, 2, 3, 4, 5, 6]), - (1720224849.338664, [], [1, 2, 3, 4, 5, 6]), - (1720311680.960628, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720593841.069028, [], [1, 2, 3, 4, 5, 6])], - [(1720193711.631887, [], [1, 2, 3, 4, 5, 6]), (1720355386.424798, [], [1, 2, 3, 4, 5, 6])], - [(1720137394.637585, [], [1, 2, 3, 4, 5, 6]), (1720227526.549035, [], [1, 2, 3, 4, 5, 6])], - [(1720601724.604091, [], [1, 2, 3, 4, 5, 6])], - [(1720242114.286726, [], [1, 2, 3, 4, 5, 6]), (1720495287.866943, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984060.976083, [], [1, 2, 3, 4, 5, 6]), - (1720233353.478142, [], [1, 2, 3, 4, 5, 6]), - (1720331822.027661, [], [1, 2, 3, 4, 5, 6]), - (1720499420.953642, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720327908.649598, [], [1, 2, 3, 4, 5, 6]), - (1720327957.004146, [], [1, 2, 3, 4, 5, 6]), - (1720328002.921775, [], [1, 2, 3, 4, 5, 6]), - (1720328054.34555, [], [1, 2, 3, 4, 5, 6]), - (1720394578.210396, [], [1, 2, 3, 4, 5, 6]), - (1720394668.213374, [], [1, 2, 3, 4, 5, 6]), - (1720394670.323029, [], [1, 2, 3, 4, 5, 6]), - (1720410358.68385, [], [1, 2, 3, 4, 5, 6]), - (1720410430.047079, [], [1, 2, 3, 4, 5, 6]), - (1720410432.093006, [], [1, 2, 3, 4, 5, 6]), - (1720485479.982584, [], [1, 2, 3, 4, 5, 6]), - (1720485552.035405, [], [1, 2, 3, 4, 5, 6]), - (1720485554.099771, [], [1, 2, 3, 4, 5, 6]), - (1720576265.461408, [], [1, 2, 3, 4, 5, 6]), - (1720576267.553332, [], [1, 2, 3, 4, 5, 6]), - (1720580196.882833, [], [1, 2, 3, 4, 5, 6]), - (1720580198.938581, [], [1, 2, 3, 4, 5, 6]), - (1720580201.66793, [], [1, 2, 3, 4, 5, 6]), - (1720580203.765767, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720512918.56325, [], [1, 2, 3, 4, 5, 6])], - [(1720587573.354151, [], [1, 2, 3, 4, 5, 6])], - [ - (1720059581.380866, [], [1, 2, 3, 4, 5, 6]), - (1720226059.821101, [], [1, 2, 3, 4, 5, 6]), - (1720569936.860231, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720483812.243251, [], [1, 2, 3, 4, 5, 6])], - [ - (1720047890.599986, [], [1, 2, 3, 4, 5, 6]), - (1720151933.610926, [], [1, 2, 3, 4, 5, 6]), - (1720426395.237753, [], [1, 2, 3, 4, 5, 6]), - (1720589584.479646, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720050613.849179, [], [1, 2, 3, 4, 5, 6]), - (1720183728.480776, [], [1, 2, 3, 4, 5, 6]), - (1720245305.222942, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974717.393306, [], [1, 2, 3, 4, 5, 6]), - (1720238913.058213, [], [1, 2, 3, 4, 5, 6]), - (1720403863.202175, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720066616.245506, [], [1, 2, 3, 4, 5, 6]), (1720329802.077257, [], [1, 2, 3, 4, 5, 6])], - [(1720058023.220462, [], [1, 2, 3, 4, 5, 6]), (1720273250.296181, [], [1, 2, 3, 4, 5, 6])], - [(1720400521.741834, [], [1, 2, 3, 4, 5, 6])], - [(1720590006.799829, [], [1, 2, 3, 4, 5, 6])], - [ - (1719977522.311193, [], [1, 2, 3, 4, 5, 6]), - (1720394307.490994, [], [1, 2, 3, 4, 5, 6]), - (1720541599.758133, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720059720.64277, [], [1, 2, 3, 4, 5, 6]), - (1720225557.277258, [], [1, 2, 3, 4, 5, 6]), - (1720318879.528985, [], [1, 2, 3, 4, 5, 6]), - (1720448939.738279, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720159019.782951, [], [1, 2, 3, 4, 5, 6]), - (1720232688.231366, [], [1, 2, 3, 4, 5, 6]), - (1720312031.934367, [], [1, 2, 3, 4, 5, 6]), - (1720420263.292336, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720051467.327131, [], [1, 2, 3, 4, 5, 6]), - (1720226107.259649, [], [1, 2, 3, 4, 5, 6]), - (1720410027.350582, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719966308.30787, [], [1, 2, 3, 4, 5, 6]), - (1720136775.382126, [], [1, 2, 3, 4, 5, 6]), - (1720453167.302523, [], [1, 2, 3, 4, 5, 6]), - (1720578911.142536, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965705.478301, [], [1, 2, 3, 4, 5, 6]), - (1720089492.274268, [], [1, 2, 3, 4, 5, 6]), - (1720458943.365803, [], [1, 2, 3, 4, 5, 6]), - (1720588170.374851, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720137202.259506, [], [1, 2, 3, 4, 5, 6]), (1720309242.730837, [], [1, 2, 3, 4, 5, 6])], - [(1720397209.557207, [], [1, 2, 3, 4, 5, 6]), (1720628958.303298, [], [1, 2, 3, 4, 5, 6])], - [(1719967303.936898, [], [1, 2, 3, 4, 5, 6]), (1720069496.922345, [], [1, 2, 3, 4, 5, 6])], - [ - (1719970996.586184, [], [1, 2, 3, 4, 5, 6]), - (1720168525.715398, [], [1, 2, 3, 4, 5, 6]), - (1720504098.515479, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720601826.09111, [], [1, 2, 3, 4, 5, 6])], - [ - (1719971199.057468, [], [1, 2, 3, 4, 5, 6]), - (1720068258.0151, [], [1, 2, 3, 4, 5, 6]), - (1720137337.044491, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719971421.175757, [], [1, 2, 3, 4, 5, 6]), (1720134959.956933, [], [1, 2, 3, 4, 5, 6])], - [ - (1719976305.13246, [], [1, 2, 3, 4, 5, 6]), - (1720059646.658845, [], [1, 2, 3, 4, 5, 6]), - (1720145964.773181, [], [1, 2, 3, 4, 5, 6]), - (1720233116.664838, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720436748.603567, [], [1, 2, 3, 4, 5, 6])], - [(1719969550.144929, [], [1, 2, 3, 4, 5, 6]), (1720315269.690666, [], [1, 2, 3, 4, 5, 6])], - [ - (1720274096.315691, [], [1, 2, 3, 4, 5, 6]), - (1720274154.981534, [], [1, 2, 3, 4, 5, 6]), - (1720274184.028094, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720268306.026574, [], [1, 2, 3, 4, 5, 6]), (1720323182.163554, [], [1, 2, 3, 4, 5, 6])], - [ - (1720032173.053995, [], [1, 2, 3, 4, 5, 6]), - (1720157155.365383, [], [1, 2, 3, 4, 5, 6]), - (1720314424.94755, [], [1, 2, 3, 4, 5, 6]), - (1720481047.114281, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720010572.095008, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968638.302149, [], [1, 2, 3, 4, 5, 6]), - (1719968762.98274, [], [1, 2, 3, 4, 5, 6]), - (1719968765.072701, [], [1, 2, 3, 4, 5, 6]), - (1720005012.137582, [], [1, 2, 3, 4, 5, 6]), - (1720005160.858454, [], [1, 2, 3, 4, 5, 6]), - (1720005162.913788, [], [1, 2, 3, 4, 5, 6]), - (1720175681.69546, [], [1, 2, 3, 4, 5, 6]), - (1720175774.033356, [], [1, 2, 3, 4, 5, 6]), - (1720175776.151125, [], [1, 2, 3, 4, 5, 6]), - (1720220252.732147, [], [1, 2, 3, 4, 5, 6]), - (1720220252.777516, [], [1, 2, 3, 4, 5, 6]), - (1720220256.747294, [], [1, 2, 3, 4, 5, 6]), - (1720492139.162569, [], [1, 2, 3, 4, 5, 6]), - (1720492141.256483, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719970987.569565, [], [1, 2, 3, 4, 5, 6])], - [(1720054508.915859, [], [1, 2, 3, 4, 5, 6]), (1720315224.08896, [], [1, 2, 3, 4, 5, 6])], - [(1720325854.156535, [], [1, 2, 3, 4, 5, 6]), (1720483854.080251, [], [1, 2, 3, 4, 5, 6])], - [(1720406510.418443, [], [1, 2, 3, 4, 5, 6])], - [ - (1720030600.544521, [], [1, 2, 3, 4, 5, 6]), - (1720069524.719771, [], [1, 2, 3, 4, 5, 6]), - (1720484112.369653, [], [1, 2, 3, 4, 5, 6]), - (1720568851.121099, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720304785.385271, [], [1, 2, 3, 4, 5, 6])], - [ - (1720313035.494802, [], [1, 2, 3, 4, 5, 6]), - (1720313090.718424, [], [1, 2, 3, 4, 5, 6]), - (1720313239.783577, [], [1, 2, 3, 4, 5, 6]), - (1720313343.042083, [], [1, 2, 3, 4, 5, 6]), - (1720404935.491204, [], [1, 2, 3, 4, 5, 6]), - (1720404979.552845, [], [1, 2, 3, 4, 5, 6]), - (1720404981.647182, [], [1, 2, 3, 4, 5, 6]), - (1720501716.284759, [], [1, 2, 3, 4, 5, 6]), - (1720501761.154088, [], [1, 2, 3, 4, 5, 6]), - (1720501763.234903, [], [1, 2, 3, 4, 5, 6]), - (1720584650.853158, [], [1, 2, 3, 4, 5, 6]), - (1720584688.899508, [], [1, 2, 3, 4, 5, 6]), - (1720584691.020015, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720229088.205557, [], [1, 2, 3, 4, 5, 6]), (1720487228.612214, [], [1, 2, 3, 4, 5, 6])], - [(1720241088.456982, [], [1, 2, 3, 4, 5, 6])], - [(1720042764.160666, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984325.782697, [], [1, 2, 3, 4, 5, 6]), - (1720047953.098659, [], [1, 2, 3, 4, 5, 6]), - (1720268267.887048, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720054622.362154, [], [1, 2, 3, 4, 5, 6]), - (1720134575.953204, [], [1, 2, 3, 4, 5, 6]), - (1720416355.096939, [], [1, 2, 3, 4, 5, 6]), - (1720500581.691615, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719972690.486054, [], [1, 2, 3, 4, 5, 6]), - (1719972877.103609, [], [1, 2, 3, 4, 5, 6]), - (1719972879.22778, [], [1, 2, 3, 4, 5, 6]), - (1719972881.797102, [], [1, 2, 3, 4, 5, 6]), - (1719972883.859612, [], [1, 2, 3, 4, 5, 6]), - (1720052338.317127, [], [1, 2, 3, 4, 5, 6]), - (1720052340.409592, [], [1, 2, 3, 4, 5, 6]), - (1720069426.554888, [], [1, 2, 3, 4, 5, 6]), - (1720069428.615973, [], [1, 2, 3, 4, 5, 6]), - (1720149027.365317, [], [1, 2, 3, 4, 5, 6]), - (1720149089.951754, [], [1, 2, 3, 4, 5, 6]), - (1720149092.012724, [], [1, 2, 3, 4, 5, 6]), - (1720234565.610403, [], [1, 2, 3, 4, 5, 6]), - (1720239125.82035, [], [1, 2, 3, 4, 5, 6]), - (1720239147.87241, [], [1, 2, 3, 4, 5, 6]), - (1720318243.573983, [], [1, 2, 3, 4, 5, 6]), - (1720318245.63705, [], [1, 2, 3, 4, 5, 6]), - (1720418009.877203, [], [1, 2, 3, 4, 5, 6]), - (1720418011.983148, [], [1, 2, 3, 4, 5, 6]), - (1720418014.464823, [], [1, 2, 3, 4, 5, 6]), - (1720485277.913378, [], [1, 2, 3, 4, 5, 6]), - (1720485280.026695, [], [1, 2, 3, 4, 5, 6]), - (1720574328.529507, [], [1, 2, 3, 4, 5, 6]), - (1720574330.633898, [], [1, 2, 3, 4, 5, 6]), - (1720581736.051228, [], [1, 2, 3, 4, 5, 6]), - (1720581766.135021, [], [1, 2, 3, 4, 5, 6]), - (1720581768.228326, [], [1, 2, 3, 4, 5, 6]), - (1720652888.715284, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720328167.133332, [], [1, 2, 3, 4, 5, 6]), (1720394291.998224, [], [1, 2, 3, 4, 5, 6])], - [(1720138278.025347, [], [1, 2, 3, 4, 5, 6])], - [(1720411684.615562, [], [1, 2, 3, 4, 5, 6])], - [ - (1719979551.790599, [], [1, 2, 3, 4, 5, 6]), - (1720062548.79153, [], [1, 2, 3, 4, 5, 6]), - (1720152645.092565, [], [1, 2, 3, 4, 5, 6]), - (1720273648.542968, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720150050.836492, [], [1, 2, 3, 4, 5, 6])], - [(1720235665.517364, [], [1, 2, 3, 4, 5, 6]), (1720504709.666893, [], [1, 2, 3, 4, 5, 6])], - [(1720502409.011067, [], [1, 2, 3, 4, 5, 6]), (1720652305.691241, [], [1, 2, 3, 4, 5, 6])], - [ - (1719983664.396995, [], [1, 2, 3, 4, 5, 6]), - (1720057964.860551, [], [1, 2, 3, 4, 5, 6]), - (1720058069.016671, [], [1, 2, 3, 4, 5, 6]), - (1720119055.986377, [], [1, 2, 3, 4, 5, 6]), - (1720119177.882926, [], [1, 2, 3, 4, 5, 6]), - (1720146988.862958, [], [1, 2, 3, 4, 5, 6]), - (1720146990.940118, [], [1, 2, 3, 4, 5, 6]), - (1720207091.824328, [], [1, 2, 3, 4, 5, 6]), - (1720207147.984162, [], [1, 2, 3, 4, 5, 6]), - (1720207150.045311, [], [1, 2, 3, 4, 5, 6]), - (1720221686.916464, [], [1, 2, 3, 4, 5, 6]), - (1720221731.792885, [], [1, 2, 3, 4, 5, 6]), - (1720221733.892091, [], [1, 2, 3, 4, 5, 6]), - (1720221736.114027, [], [1, 2, 3, 4, 5, 6]), - (1720221738.1731, [], [1, 2, 3, 4, 5, 6]), - (1720221740.137735, [], [1, 2, 3, 4, 5, 6]), - (1720221742.219472, [], [1, 2, 3, 4, 5, 6]), - (1720319188.083254, [], [1, 2, 3, 4, 5, 6]), - (1720319190.195166, [], [1, 2, 3, 4, 5, 6]), - (1720333160.336537, [], [1, 2, 3, 4, 5, 6]), - (1720333162.39224, [], [1, 2, 3, 4, 5, 6]), - (1720350382.882768, [], [1, 2, 3, 4, 5, 6]), - (1720350384.998862, [], [1, 2, 3, 4, 5, 6]), - (1720350385.400746, [], [1, 2, 3, 4, 5, 6]), - (1720350387.504804, [], [1, 2, 3, 4, 5, 6]), - (1720350390.868713, [], [1, 2, 3, 4, 5, 6]), - (1720350392.929211, [], [1, 2, 3, 4, 5, 6]), - (1720482928.905461, [], [1, 2, 3, 4, 5, 6]), - (1720482987.630373, [], [1, 2, 3, 4, 5, 6]), - (1720549510.694147, [], [1, 2, 3, 4, 5, 6]), - (1720549582.87966, [], [1, 2, 3, 4, 5, 6]), - (1720549584.95341, [], [1, 2, 3, 4, 5, 6]), - (1720581476.586746, [], [1, 2, 3, 4, 5, 6]), - (1720581478.656771, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977177.729628, [], [1, 2, 3, 4, 5, 6]), (1720393638.078415, [], [1, 2, 3, 4, 5, 6])], - [ - (1719980378.113974, [], [1, 2, 3, 4, 5, 6]), - (1720443102.049493, [], [1, 2, 3, 4, 5, 6]), - (1720590770.939412, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719979883.308045, [], [1, 2, 3, 4, 5, 6]), - (1720230654.923495, [], [1, 2, 3, 4, 5, 6]), - (1720310908.910099, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719964829.898192, [], [1, 2, 3, 4, 5, 6]), - (1719964832.003811, [], [1, 2, 3, 4, 5, 6]), - (1719985240.876339, [], [1, 2, 3, 4, 5, 6]), - (1719985242.911416, [], [1, 2, 3, 4, 5, 6]), - (1719985243.633507, [], [1, 2, 3, 4, 5, 6]), - (1719985245.665729, [], [1, 2, 3, 4, 5, 6]), - (1720060650.829248, [], [1, 2, 3, 4, 5, 6]), - (1720060759.718692, [], [1, 2, 3, 4, 5, 6]), - (1720060761.830242, [], [1, 2, 3, 4, 5, 6]), - (1720070260.443094, [], [1, 2, 3, 4, 5, 6]), - (1720070280.911994, [], [1, 2, 3, 4, 5, 6]), - (1720070282.979246, [], [1, 2, 3, 4, 5, 6]), - (1720134645.425223, [], [1, 2, 3, 4, 5, 6]), - (1720134793.819981, [], [1, 2, 3, 4, 5, 6]), - (1720134795.932398, [], [1, 2, 3, 4, 5, 6]), - (1720155938.192604, [], [1, 2, 3, 4, 5, 6]), - (1720155940.320279, [], [1, 2, 3, 4, 5, 6]), - (1720155945.041101, [], [1, 2, 3, 4, 5, 6]), - (1720155947.088061, [], [1, 2, 3, 4, 5, 6]), - (1720236895.111761, [], [1, 2, 3, 4, 5, 6]), - (1720236912.473535, [], [1, 2, 3, 4, 5, 6]), - (1720236914.593968, [], [1, 2, 3, 4, 5, 6]), - (1720236917.655587, [], [1, 2, 3, 4, 5, 6]), - (1720318871.824625, [], [1, 2, 3, 4, 5, 6]), - (1720318935.358285, [], [1, 2, 3, 4, 5, 6]), - (1720318937.446561, [], [1, 2, 3, 4, 5, 6]), - (1720318940.05207, [], [1, 2, 3, 4, 5, 6]), - (1720318942.106239, [], [1, 2, 3, 4, 5, 6]), - (1720405217.370251, [], [1, 2, 3, 4, 5, 6]), - (1720405312.528519, [], [1, 2, 3, 4, 5, 6]), - (1720405314.627163, [], [1, 2, 3, 4, 5, 6]), - (1720413100.204244, [], [1, 2, 3, 4, 5, 6]), - (1720413102.291035, [], [1, 2, 3, 4, 5, 6]), - (1720496542.308228, [], [1, 2, 3, 4, 5, 6]), - (1720574260.260325, [], [1, 2, 3, 4, 5, 6]), - (1720574343.117651, [], [1, 2, 3, 4, 5, 6]), - (1720574345.20748, [], [1, 2, 3, 4, 5, 6]), - (1720578705.104516, [], [1, 2, 3, 4, 5, 6]), - (1720578717.159504, [], [1, 2, 3, 4, 5, 6]), - (1720578719.26077, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720071370.538676, [], [1, 2, 3, 4, 5, 6])], - [(1719972220.86175, [], [1, 2, 3, 4, 5, 6]), (1720227223.558904, [], [1, 2, 3, 4, 5, 6])], - [ - (1720047692.206123, [], [1, 2, 3, 4, 5, 6]), - (1720074479.043983, [], [1, 2, 3, 4, 5, 6]), - (1720221755.131247, [], [1, 2, 3, 4, 5, 6]), - (1720343377.429715, [], [1, 2, 3, 4, 5, 6]), - (1720581159.65796, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720054906.379171, [], [1, 2, 3, 4, 5, 6]), - (1720326827.193456, [], [1, 2, 3, 4, 5, 6]), - (1720395837.565662, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719972411.855532, [], [1, 2, 3, 4, 5, 6]), - (1719972538.863121, [], [1, 2, 3, 4, 5, 6]), - (1719972540.935712, [], [1, 2, 3, 4, 5, 6]), - (1720063717.900878, [], [1, 2, 3, 4, 5, 6]), - (1720063719.954111, [], [1, 2, 3, 4, 5, 6]), - (1720070114.807467, [], [1, 2, 3, 4, 5, 6]), - (1720070235.024434, [], [1, 2, 3, 4, 5, 6]), - (1720070237.14674, [], [1, 2, 3, 4, 5, 6]), - (1720097819.236115, [], [1, 2, 3, 4, 5, 6]), - (1720097978.260021, [], [1, 2, 3, 4, 5, 6]), - (1720097980.382821, [], [1, 2, 3, 4, 5, 6]), - (1720151026.716063, [], [1, 2, 3, 4, 5, 6]), - (1720151173.670938, [], [1, 2, 3, 4, 5, 6]), - (1720151175.717239, [], [1, 2, 3, 4, 5, 6]), - (1720166439.941955, [], [1, 2, 3, 4, 5, 6]), - (1720166583.693905, [], [1, 2, 3, 4, 5, 6]), - (1720166585.791065, [], [1, 2, 3, 4, 5, 6]), - (1720181553.630642, [], [1, 2, 3, 4, 5, 6]), - (1720181555.746202, [], [1, 2, 3, 4, 5, 6]), - (1720242210.300006, [], [1, 2, 3, 4, 5, 6]), - (1720242331.451228, [], [1, 2, 3, 4, 5, 6]), - (1720316730.127117, [], [1, 2, 3, 4, 5, 6]), - (1720316751.481651, [], [1, 2, 3, 4, 5, 6]), - (1720350332.517593, [], [1, 2, 3, 4, 5, 6]), - (1720350427.724851, [], [1, 2, 3, 4, 5, 6]), - (1720350429.836812, [], [1, 2, 3, 4, 5, 6]), - (1720396153.382808, [], [1, 2, 3, 4, 5, 6]), - (1720396199.106453, [], [1, 2, 3, 4, 5, 6]), - (1720396201.15929, [], [1, 2, 3, 4, 5, 6]), - (1720424092.525755, [], [1, 2, 3, 4, 5, 6]), - (1720424190.959176, [], [1, 2, 3, 4, 5, 6]), - (1720424193.037739, [], [1, 2, 3, 4, 5, 6]), - (1720492456.877253, [], [1, 2, 3, 4, 5, 6]), - (1720492529.103048, [], [1, 2, 3, 4, 5, 6]), - (1720492531.198928, [], [1, 2, 3, 4, 5, 6]), - (1720583806.008143, [], [1, 2, 3, 4, 5, 6]), - (1720583868.43082, [], [1, 2, 3, 4, 5, 6]), - (1720648763.855471, [], [1, 2, 3, 4, 5, 6]), - (1720648878.799852, [], [1, 2, 3, 4, 5, 6]), - (1720648880.882297, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720071793.774403, [], [1, 2, 3, 4, 5, 6]), - (1720309002.505766, [], [1, 2, 3, 4, 5, 6]), - (1720367384.379119, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978345.677095, [], [1, 2, 3, 4, 5, 6]), (1720134660.416426, [], [1, 2, 3, 4, 5, 6])], - [ - (1720056400.339178, [], [1, 2, 3, 4, 5, 6]), - (1720137451.906538, [], [1, 2, 3, 4, 5, 6]), - (1720581731.115191, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719974999.631834, [], [1, 2, 3, 4, 5, 6]), (1720503857.499785, [], [1, 2, 3, 4, 5, 6])], - [(1720325249.830373, [], [1, 2, 3, 4, 5, 6])], - [ - (1719970175.486046, [], [1, 2, 3, 4, 5, 6]), - (1720061532.244847, [], [1, 2, 3, 4, 5, 6]), - (1720387059.054565, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720157797.242967, [], [1, 2, 3, 4, 5, 6])], - [(1720490173.84352, [], [1, 2, 3, 4, 5, 6])], - [(1720568387.145132, [], [1, 2, 3, 4, 5, 6])], - [(1720027447.264569, [], [1, 2, 3, 4, 5, 6])], - [(1719979106.899872, [], [1, 2, 3, 4, 5, 6]), (1720417473.653713, [], [1, 2, 3, 4, 5, 6])], - [(1720153359.982848, [], [1, 2, 3, 4, 5, 6]), (1720468837.459019, [], [1, 2, 3, 4, 5, 6])], - [(1720047669.218866, [], [1, 2, 3, 4, 5, 6])], - [(1720230050.113895, [], [1, 2, 3, 4, 5, 6])], - [ - (1719975411.228945, [], [1, 2, 3, 4, 5, 6]), - (1720235199.496284, [], [1, 2, 3, 4, 5, 6]), - (1720403154.17646, [], [1, 2, 3, 4, 5, 6]), - (1720626578.282517, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978136.275137, [], [1, 2, 3, 4, 5, 6]), (1720331670.572264, [], [1, 2, 3, 4, 5, 6])], - [ - (1719975669.597909, [], [1, 2, 3, 4, 5, 6]), - (1719975763.25366, [], [1, 2, 3, 4, 5, 6]), - (1720055306.937976, [], [1, 2, 3, 4, 5, 6]), - (1720055449.351479, [], [1, 2, 3, 4, 5, 6]), - (1720067433.572041, [], [1, 2, 3, 4, 5, 6]), - (1720067452.84519, [], [1, 2, 3, 4, 5, 6]), - (1720067454.935816, [], [1, 2, 3, 4, 5, 6]), - (1720233716.974937, [], [1, 2, 3, 4, 5, 6]), - (1720233884.056907, [], [1, 2, 3, 4, 5, 6]), - (1720233886.107033, [], [1, 2, 3, 4, 5, 6]), - (1720238869.144339, [], [1, 2, 3, 4, 5, 6]), - (1720239054.729577, [], [1, 2, 3, 4, 5, 6]), - (1720239056.811577, [], [1, 2, 3, 4, 5, 6]), - (1720248048.594017, [], [1, 2, 3, 4, 5, 6]), - (1720248147.506317, [], [1, 2, 3, 4, 5, 6]), - (1720248149.540209, [], [1, 2, 3, 4, 5, 6]), - (1720323761.342714, [], [1, 2, 3, 4, 5, 6]), - (1720323763.381547, [], [1, 2, 3, 4, 5, 6]), - (1720400825.240853, [], [1, 2, 3, 4, 5, 6]), - (1720400844.815642, [], [1, 2, 3, 4, 5, 6]), - (1720410954.1329, [], [1, 2, 3, 4, 5, 6]), - (1720410956.230411, [], [1, 2, 3, 4, 5, 6]), - (1720410956.661655, [], [1, 2, 3, 4, 5, 6]), - (1720410958.800282, [], [1, 2, 3, 4, 5, 6]), - (1720414005.128157, [], [1, 2, 3, 4, 5, 6]), - (1720414035.742095, [], [1, 2, 3, 4, 5, 6]), - (1720414037.861356, [], [1, 2, 3, 4, 5, 6]), - (1720414039.522054, [], [1, 2, 3, 4, 5, 6]), - (1720414041.622559, [], [1, 2, 3, 4, 5, 6]), - (1720449836.553695, [], [1, 2, 3, 4, 5, 6]), - (1720449909.88067, [], [1, 2, 3, 4, 5, 6]), - (1720449912.006572, [], [1, 2, 3, 4, 5, 6]), - (1720504478.640048, [], [1, 2, 3, 4, 5, 6]), - (1720504584.183246, [], [1, 2, 3, 4, 5, 6]), - (1720504586.273448, [], [1, 2, 3, 4, 5, 6]), - (1720589586.941948, [], [1, 2, 3, 4, 5, 6]), - (1720589732.653657, [], [1, 2, 3, 4, 5, 6]), - (1720589734.757411, [], [1, 2, 3, 4, 5, 6]), - (1720589735.718174, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719987925.192586, [], [1, 2, 3, 4, 5, 6]), (1720319498.157106, [], [1, 2, 3, 4, 5, 6])], - [(1720140316.935341, [], [1, 2, 3, 4, 5, 6]), (1720581286.138288, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984942.453601, [], [1, 2, 3, 4, 5, 6]), - (1720334036.972544, [], [1, 2, 3, 4, 5, 6]), - (1720568302.136228, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720231990.896895, [], [1, 2, 3, 4, 5, 6]), (1720320392.727402, [], [1, 2, 3, 4, 5, 6])], - [(1720151072.246138, [], [1, 2, 3, 4, 5, 6]), (1720309428.675922, [], [1, 2, 3, 4, 5, 6])], - [(1720652752.302257, [], [1, 2, 3, 4, 5, 6])], - [ - (1719977332.758786, [], [1, 2, 3, 4, 5, 6]), - (1720135118.942837, [], [1, 2, 3, 4, 5, 6]), - (1720498977.766189, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720054300.10225, [], [1, 2, 3, 4, 5, 6]), (1720419250.119038, [], [1, 2, 3, 4, 5, 6])], - [ - (1720170242.586928, [], [1, 2, 3, 4, 5, 6]), - (1720322954.401713, [], [1, 2, 3, 4, 5, 6]), - (1720500416.057333, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719976447.157218, [], [1, 2, 3, 4, 5, 6])], - [(1720134454.623643, [], [1, 2, 3, 4, 5, 6]), (1720482790.529945, [], [1, 2, 3, 4, 5, 6])], - [(1720575291.374898, [], [1, 2, 3, 4, 5, 6])], - [(1720575147.912954, [], [1, 2, 3, 4, 5, 6])], - [ - (1719997197.65312, [], [1, 2, 3, 4, 5, 6]), - (1720137704.47896, [], [1, 2, 3, 4, 5, 6]), - (1720226085.527498, [], [1, 2, 3, 4, 5, 6]), - (1720306837.86921, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720314781.298338, [], [1, 2, 3, 4, 5, 6]), (1720443503.319112, [], [1, 2, 3, 4, 5, 6])], - [ - (1719976515.23989, [], [1, 2, 3, 4, 5, 6]), - (1720225806.720086, [], [1, 2, 3, 4, 5, 6]), - (1720388901.256231, [], [1, 2, 3, 4, 5, 6]), - (1720490185.842396, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720568142.650151, [], [1, 2, 3, 4, 5, 6])], - [(1720587602.828532, [], [1, 2, 3, 4, 5, 6])], - [(1720228569.783763, [], [1, 2, 3, 4, 5, 6]), (1720577136.698764, [], [1, 2, 3, 4, 5, 6])], - [ - (1720058398.793045, [], [1, 2, 3, 4, 5, 6]), - (1720317616.711315, [], [1, 2, 3, 4, 5, 6]), - (1720498994.241943, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719988512.009335, [], [1, 2, 3, 4, 5, 6]), - (1720411879.880695, [], [1, 2, 3, 4, 5, 6]), - (1720575546.218164, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720245099.046699, [], [1, 2, 3, 4, 5, 6]), (1720652539.847041, [], [1, 2, 3, 4, 5, 6])], - [ - (1719965518.303227, [], [1, 2, 3, 4, 5, 6]), - (1720241249.736668, [], [1, 2, 3, 4, 5, 6]), - (1720410560.906617, [], [1, 2, 3, 4, 5, 6]), - (1720566388.427971, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720033619.669265, [], [1, 2, 3, 4, 5, 6]), - (1720309514.690673, [], [1, 2, 3, 4, 5, 6]), - (1720584737.484501, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719981137.891986, [], [1, 2, 3, 4, 5, 6]), - (1719981255.525287, [], [1, 2, 3, 4, 5, 6]), - (1719981257.57542, [], [1, 2, 3, 4, 5, 6]), - (1720156254.934266, [], [1, 2, 3, 4, 5, 6]), - (1720156432.088183, [], [1, 2, 3, 4, 5, 6]), - (1720221245.352908, [], [1, 2, 3, 4, 5, 6]), - (1720221247.415618, [], [1, 2, 3, 4, 5, 6]), - (1720306695.430622, [], [1, 2, 3, 4, 5, 6]), - (1720306697.509606, [], [1, 2, 3, 4, 5, 6]), - (1720399726.625066, [], [1, 2, 3, 4, 5, 6]), - (1720399728.675873, [], [1, 2, 3, 4, 5, 6]), - (1720486842.405361, [], [1, 2, 3, 4, 5, 6]), - (1720486974.649877, [], [1, 2, 3, 4, 5, 6]), - (1720494605.919949, [], [1, 2, 3, 4, 5, 6]), - (1720494724.480053, [], [1, 2, 3, 4, 5, 6]), - (1720494726.541559, [], [1, 2, 3, 4, 5, 6]), - (1720572824.284783, [], [1, 2, 3, 4, 5, 6]), - (1720572826.355789, [], [1, 2, 3, 4, 5, 6]), - (1720652512.753893, [], [1, 2, 3, 4, 5, 6]), - (1720652514.833743, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720044224.653908, [], [1, 2, 3, 4, 5, 6]), (1720583176.852571, [], [1, 2, 3, 4, 5, 6])], - [(1720567262.122889, [], [1, 2, 3, 4, 5, 6])], - [(1720518049.925836, [], [1, 2, 3, 4, 5, 6])], - [(1720148280.678113, [], [1, 2, 3, 4, 5, 6]), (1720391739.484219, [], [1, 2, 3, 4, 5, 6])], - [ - (1719983654.268169, [], [1, 2, 3, 4, 5, 6]), - (1719983761.844014, [], [1, 2, 3, 4, 5, 6]), - (1719983763.902973, [], [1, 2, 3, 4, 5, 6]), - (1720014262.846562, [], [1, 2, 3, 4, 5, 6]), - (1720014264.966534, [], [1, 2, 3, 4, 5, 6]), - (1720014268.064236, [], [1, 2, 3, 4, 5, 6]), - (1720014270.176366, [], [1, 2, 3, 4, 5, 6]), - (1720062164.847608, [], [1, 2, 3, 4, 5, 6]), - (1720062166.93557, [], [1, 2, 3, 4, 5, 6]), - (1720070760.286042, [], [1, 2, 3, 4, 5, 6]), - (1720070793.879274, [], [1, 2, 3, 4, 5, 6]), - (1720070795.974998, [], [1, 2, 3, 4, 5, 6]), - (1720136175.682667, [], [1, 2, 3, 4, 5, 6]), - (1720136177.782735, [], [1, 2, 3, 4, 5, 6]), - (1720150756.421019, [], [1, 2, 3, 4, 5, 6]), - (1720150758.537073, [], [1, 2, 3, 4, 5, 6]), - (1720226712.358545, [], [1, 2, 3, 4, 5, 6]), - (1720320316.371588, [], [1, 2, 3, 4, 5, 6]), - (1720396676.623722, [], [1, 2, 3, 4, 5, 6]), - (1720396759.330429, [], [1, 2, 3, 4, 5, 6]), - (1720482810.511366, [], [1, 2, 3, 4, 5, 6]), - (1720482891.609285, [], [1, 2, 3, 4, 5, 6]), - (1720482893.739553, [], [1, 2, 3, 4, 5, 6]), - (1720502988.652815, [], [1, 2, 3, 4, 5, 6]), - (1720503034.447086, [], [1, 2, 3, 4, 5, 6]), - (1720503036.52898, [], [1, 2, 3, 4, 5, 6]), - (1720503036.606516, [], [1, 2, 3, 4, 5, 6]), - (1720503038.712119, [], [1, 2, 3, 4, 5, 6]), - (1720566567.148583, [], [1, 2, 3, 4, 5, 6]), - (1720566710.618717, [], [1, 2, 3, 4, 5, 6]), - (1720624425.022175, [], [1, 2, 3, 4, 5, 6]), - (1720624567.571474, [], [1, 2, 3, 4, 5, 6]), - (1720624569.66289, [], [1, 2, 3, 4, 5, 6]), - (1720652508.525789, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978793.297818, [], [1, 2, 3, 4, 5, 6]), (1720312690.624643, [], [1, 2, 3, 4, 5, 6])], - [(1720408103.17786, [], [1, 2, 3, 4, 5, 6]), (1720496665.901316, [], [1, 2, 3, 4, 5, 6])], - [(1720397084.267673, [], [1, 2, 3, 4, 5, 6]), (1720499411.209847, [], [1, 2, 3, 4, 5, 6])], - [ - (1720111853.777887, [], [1, 2, 3, 4, 5, 6]), - (1720111923.412934, [], [1, 2, 3, 4, 5, 6]), - (1720139482.167685, [], [1, 2, 3, 4, 5, 6]), - (1720139533.842338, [], [1, 2, 3, 4, 5, 6]), - (1720139535.907287, [], [1, 2, 3, 4, 5, 6]), - (1720139540.267313, [], [1, 2, 3, 4, 5, 6]), - (1720139542.34773, [], [1, 2, 3, 4, 5, 6]), - (1720139547.051966, [], [1, 2, 3, 4, 5, 6]), - (1720139549.136732, [], [1, 2, 3, 4, 5, 6]), - (1720464344.794745, [], [1, 2, 3, 4, 5, 6]), - (1720464401.900918, [], [1, 2, 3, 4, 5, 6]), - (1720464404.029255, [], [1, 2, 3, 4, 5, 6]), - (1720498850.875209, [], [1, 2, 3, 4, 5, 6]), - (1720499103.608103, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719973523.458065, [], [1, 2, 3, 4, 5, 6]), (1720233566.787523, [], [1, 2, 3, 4, 5, 6])], - [(1720407928.090004, [], [1, 2, 3, 4, 5, 6])], - [(1720032729.148346, [], [1, 2, 3, 4, 5, 6]), (1720062532.225999, [], [1, 2, 3, 4, 5, 6])], - [(1720034095.862663, [], [1, 2, 3, 4, 5, 6]), (1720491285.681862, [], [1, 2, 3, 4, 5, 6])], - [(1720096472.997597, [], [1, 2, 3, 4, 5, 6]), (1720568056.766425, [], [1, 2, 3, 4, 5, 6])], - [(1720138718.911672, [], [1, 2, 3, 4, 5, 6])], - [ - (1720336998.597537, [], [1, 2, 3, 4, 5, 6]), - (1720489473.142035, [], [1, 2, 3, 4, 5, 6]), - (1720574315.596422, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720577328.151149, [], [1, 2, 3, 4, 5, 6])], - [(1720072713.69671, [], [1, 2, 3, 4, 5, 6]), (1720231002.690818, [], [1, 2, 3, 4, 5, 6])], - [(1719966317.997493, [], [1, 2, 3, 4, 5, 6]), (1720238108.647106, [], [1, 2, 3, 4, 5, 6])], - [(1720146847.656681, [], [1, 2, 3, 4, 5, 6])], - [(1720239981.42926, [], [1, 2, 3, 4, 5, 6])], - [(1720081339.444776, [], [1, 2, 3, 4, 5, 6]), (1720234051.371763, [], [1, 2, 3, 4, 5, 6])], - [(1720236937.844197, [], [1, 2, 3, 4, 5, 6]), (1720501314.981075, [], [1, 2, 3, 4, 5, 6])], - [(1720495611.198831, [], [1, 2, 3, 4, 5, 6])], - [(1720071452.84595, [], [1, 2, 3, 4, 5, 6])], - [(1720320971.754361, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982790.224924, [], [1, 2, 3, 4, 5, 6]), - (1719982861.078823, [], [1, 2, 3, 4, 5, 6]), - (1719982863.122702, [], [1, 2, 3, 4, 5, 6]), - (1720052453.241504, [], [1, 2, 3, 4, 5, 6]), - (1720052505.408448, [], [1, 2, 3, 4, 5, 6]), - (1720052507.485592, [], [1, 2, 3, 4, 5, 6]), - (1720078456.868981, [], [1, 2, 3, 4, 5, 6]), - (1720137047.584706, [], [1, 2, 3, 4, 5, 6]), - (1720137124.096958, [], [1, 2, 3, 4, 5, 6]), - (1720137126.192241, [], [1, 2, 3, 4, 5, 6]), - (1720155528.420602, [], [1, 2, 3, 4, 5, 6]), - (1720155596.835697, [], [1, 2, 3, 4, 5, 6]), - (1720155598.919376, [], [1, 2, 3, 4, 5, 6]), - (1720204090.330488, [], [1, 2, 3, 4, 5, 6]), - (1720204222.690243, [], [1, 2, 3, 4, 5, 6]), - (1720204224.805824, [], [1, 2, 3, 4, 5, 6]), - (1720232760.467367, [], [1, 2, 3, 4, 5, 6]), - (1720232859.977733, [], [1, 2, 3, 4, 5, 6]), - (1720242903.930897, [], [1, 2, 3, 4, 5, 6]), - (1720242906.021355, [], [1, 2, 3, 4, 5, 6]), - (1720309697.411345, [], [1, 2, 3, 4, 5, 6]), - (1720309699.483954, [], [1, 2, 3, 4, 5, 6]), - (1720406346.354509, [], [1, 2, 3, 4, 5, 6]), - (1720406523.466919, [], [1, 2, 3, 4, 5, 6]), - (1720406525.535072, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720065979.154591, [], [1, 2, 3, 4, 5, 6]), (1720325699.423285, [], [1, 2, 3, 4, 5, 6])], - [(1720244750.093352, [], [1, 2, 3, 4, 5, 6]), (1720394343.192185, [], [1, 2, 3, 4, 5, 6])], - [(1720193298.590097, [], [1, 2, 3, 4, 5, 6]), (1720315677.193089, [], [1, 2, 3, 4, 5, 6])], - [(1720501281.07252, [], [1, 2, 3, 4, 5, 6])], - [(1720055721.622214, [], [1, 2, 3, 4, 5, 6])], - [ - (1720137839.895581, [], [1, 2, 3, 4, 5, 6]), - (1720231251.548774, [], [1, 2, 3, 4, 5, 6]), - (1720350224.693877, [], [1, 2, 3, 4, 5, 6]), - (1720519304.741337, [], [1, 2, 3, 4, 5, 6]), - (1720586487.784295, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719969181.053709, [], [1, 2, 3, 4, 5, 6]), (1720434586.266895, [], [1, 2, 3, 4, 5, 6])], - [(1720070912.148493, [], [1, 2, 3, 4, 5, 6])], - [(1720244703.673132, [], [1, 2, 3, 4, 5, 6]), (1720494833.034907, [], [1, 2, 3, 4, 5, 6])], - [ - (1720053732.993216, [], [1, 2, 3, 4, 5, 6]), - (1720053735.086697, [], [1, 2, 3, 4, 5, 6]), - (1720081490.114819, [], [1, 2, 3, 4, 5, 6]), - (1720081492.188923, [], [1, 2, 3, 4, 5, 6]), - (1720108329.744396, [], [1, 2, 3, 4, 5, 6]), - (1720108420.858541, [], [1, 2, 3, 4, 5, 6]), - (1720108422.93886, [], [1, 2, 3, 4, 5, 6]), - (1720142971.786605, [], [1, 2, 3, 4, 5, 6]), - (1720143021.896153, [], [1, 2, 3, 4, 5, 6]), - (1720149975.921352, [], [1, 2, 3, 4, 5, 6]), - (1720150041.125351, [], [1, 2, 3, 4, 5, 6]), - (1720150043.15518, [], [1, 2, 3, 4, 5, 6]), - (1720200733.408027, [], [1, 2, 3, 4, 5, 6]), - (1720200744.366236, [], [1, 2, 3, 4, 5, 6]), - (1720200746.48024, [], [1, 2, 3, 4, 5, 6]), - (1720226248.428928, [], [1, 2, 3, 4, 5, 6]), - (1720226387.261389, [], [1, 2, 3, 4, 5, 6]), - (1720325189.273212, [], [1, 2, 3, 4, 5, 6]), - (1720367266.448359, [], [1, 2, 3, 4, 5, 6]), - (1720367268.528501, [], [1, 2, 3, 4, 5, 6]), - (1720397514.119584, [], [1, 2, 3, 4, 5, 6]), - (1720397583.541623, [], [1, 2, 3, 4, 5, 6]), - (1720397585.62972, [], [1, 2, 3, 4, 5, 6]), - (1720407649.068004, [], [1, 2, 3, 4, 5, 6]), - (1720407859.450723, [], [1, 2, 3, 4, 5, 6]), - (1720407861.5267, [], [1, 2, 3, 4, 5, 6]), - (1720418226.184583, [], [1, 2, 3, 4, 5, 6]), - (1720418312.907521, [], [1, 2, 3, 4, 5, 6]), - (1720418312.959891, [], [1, 2, 3, 4, 5, 6]), - (1720418314.508588, [], [1, 2, 3, 4, 5, 6]), - (1720429033.410454, [], [1, 2, 3, 4, 5, 6]), - (1720429217.5183, [], [1, 2, 3, 4, 5, 6]), - (1720429219.58254, [], [1, 2, 3, 4, 5, 6]), - (1720476196.299215, [], [1, 2, 3, 4, 5, 6]), - (1720476290.414317, [], [1, 2, 3, 4, 5, 6]), - (1720476292.497993, [], [1, 2, 3, 4, 5, 6]), - (1720496668.635514, [], [1, 2, 3, 4, 5, 6]), - (1720496670.762669, [], [1, 2, 3, 4, 5, 6]), - (1720566807.578929, [], [1, 2, 3, 4, 5, 6]), - (1720566881.524889, [], [1, 2, 3, 4, 5, 6]), - (1720566883.613068, [], [1, 2, 3, 4, 5, 6]), - (1720575742.398153, [], [1, 2, 3, 4, 5, 6]), - (1720575760.407369, [], [1, 2, 3, 4, 5, 6]), - (1720575762.530879, [], [1, 2, 3, 4, 5, 6]), - (1720623060.799492, [], [1, 2, 3, 4, 5, 6]), - (1720623163.775703, [], [1, 2, 3, 4, 5, 6]), - (1720623165.819144, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720490829.088908, [], [1, 2, 3, 4, 5, 6])], - [ - (1720222040.449568, [], [1, 2, 3, 4, 5, 6]), - (1720328183.580613, [], [1, 2, 3, 4, 5, 6]), - (1720581997.108309, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720631726.024509, [], [1, 2, 3, 4, 5, 6])], - [ - (1719969186.42388, [], [1, 2, 3, 4, 5, 6]), - (1720236467.453142, [], [1, 2, 3, 4, 5, 6]), - (1720460294.599805, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720328624.599959, [], [1, 2, 3, 4, 5, 6]), - (1720411036.02508, [], [1, 2, 3, 4, 5, 6]), - (1720470233.314202, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719966062.758672, [], [1, 2, 3, 4, 5, 6]), - (1720057471.705526, [], [1, 2, 3, 4, 5, 6]), - (1720325034.717518, [], [1, 2, 3, 4, 5, 6]), - (1720407309.902625, [], [1, 2, 3, 4, 5, 6]), - (1720573477.911506, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720063887.70449, [], [1, 2, 3, 4, 5, 6])], - [(1720343326.152899, [], [1, 2, 3, 4, 5, 6])], - [(1720411362.644921, [], [1, 2, 3, 4, 5, 6])], - [(1720395606.751317, [], [1, 2, 3, 4, 5, 6])], - [(1720155980.858558, [], [1, 2, 3, 4, 5, 6])], - [(1720450339.669296, [], [1, 2, 3, 4, 5, 6])], - [(1719981567.460091, [], [1, 2, 3, 4, 5, 6]), (1720587320.169523, [], [1, 2, 3, 4, 5, 6])], - [(1720245122.915738, [], [1, 2, 3, 4, 5, 6])], - [(1719970229.063219, [], [1, 2, 3, 4, 5, 6]), (1720488361.805483, [], [1, 2, 3, 4, 5, 6])], - [(1720320009.047059, [], [1, 2, 3, 4, 5, 6])], - [(1720139484.708505, [], [1, 2, 3, 4, 5, 6]), (1720396780.73649, [], [1, 2, 3, 4, 5, 6])], - [(1720238094.386701, [], [1, 2, 3, 4, 5, 6])], - [(1720627574.598265, [], [1, 2, 3, 4, 5, 6])], - [(1720136834.089355, [], [1, 2, 3, 4, 5, 6]), (1720396824.609765, [], [1, 2, 3, 4, 5, 6])], - [(1720225652.369657, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982133.012616, [], [1, 2, 3, 4, 5, 6]), - (1719982177.631804, [], [1, 2, 3, 4, 5, 6]), - (1719982179.720602, [], [1, 2, 3, 4, 5, 6]), - (1720006591.274361, [], [1, 2, 3, 4, 5, 6]), - (1720006644.930183, [], [1, 2, 3, 4, 5, 6]), - (1720006647.03435, [], [1, 2, 3, 4, 5, 6]), - (1720460548.964008, [], [1, 2, 3, 4, 5, 6]), - (1720460614.237345, [], [1, 2, 3, 4, 5, 6]), - (1720460616.332418, [], [1, 2, 3, 4, 5, 6]), - (1720585282.645498, [], [1, 2, 3, 4, 5, 6]), - (1720585293.462072, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720370572.550118, [], [1, 2, 3, 4, 5, 6])], - [ - (1719973160.879923, [], [1, 2, 3, 4, 5, 6]), - (1720329101.982409, [], [1, 2, 3, 4, 5, 6]), - (1720581501.430356, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720063998.039445, [], [1, 2, 3, 4, 5, 6]), - (1720232764.384684, [], [1, 2, 3, 4, 5, 6]), - (1720502473.633051, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720153647.635598, [], [1, 2, 3, 4, 5, 6]), - (1720225923.85076, [], [1, 2, 3, 4, 5, 6]), - (1720413430.570698, [], [1, 2, 3, 4, 5, 6]), - (1720584131.042756, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719966759.043742, [], [1, 2, 3, 4, 5, 6])], - [(1720405936.570297, [], [1, 2, 3, 4, 5, 6])], - [(1720144919.519677, [], [1, 2, 3, 4, 5, 6]), (1720402676.1685, [], [1, 2, 3, 4, 5, 6])], - [(1720402994.034134, [], [1, 2, 3, 4, 5, 6]), (1720497341.728864, [], [1, 2, 3, 4, 5, 6])], - [ - (1719973785.927392, [], [1, 2, 3, 4, 5, 6]), - (1720142506.754009, [], [1, 2, 3, 4, 5, 6]), - (1720312482.395361, [], [1, 2, 3, 4, 5, 6]), - (1720578049.42885, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720143203.796648, [], [1, 2, 3, 4, 5, 6]), (1720504600.034248, [], [1, 2, 3, 4, 5, 6])], - [(1720138317.024564, [], [1, 2, 3, 4, 5, 6]), (1720307922.860078, [], [1, 2, 3, 4, 5, 6])], - [(1720576710.045341, [], [1, 2, 3, 4, 5, 6])], - [ - (1720237948.24219, [], [1, 2, 3, 4, 5, 6]), - (1720322691.233406, [], [1, 2, 3, 4, 5, 6]), - (1720412663.957815, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720342019.617667, [], [1, 2, 3, 4, 5, 6]), - (1720342090.227667, [], [1, 2, 3, 4, 5, 6]), - (1720342263.731169, [], [1, 2, 3, 4, 5, 6]), - (1720342307.569989, [], [1, 2, 3, 4, 5, 6]), - (1720342413.538738, [], [1, 2, 3, 4, 5, 6]), - (1720342570.868506, [], [1, 2, 3, 4, 5, 6]), - (1720342664.423143, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720053725.982337, [], [1, 2, 3, 4, 5, 6]), - (1720137089.95596, [], [1, 2, 3, 4, 5, 6]), - (1720250340.159455, [], [1, 2, 3, 4, 5, 6]), - (1720408080.82431, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720502215.54816, [], [1, 2, 3, 4, 5, 6])], - [(1720051018.757074, [], [1, 2, 3, 4, 5, 6]), (1720221304.68857, [], [1, 2, 3, 4, 5, 6])], - [ - (1720055639.220711, [], [1, 2, 3, 4, 5, 6]), - (1720242136.136068, [], [1, 2, 3, 4, 5, 6]), - (1720501308.452889, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720210019.832882, [], [1, 2, 3, 4, 5, 6])], - [(1720222496.41532, [], [1, 2, 3, 4, 5, 6])], - [(1720221892.596089, [], [1, 2, 3, 4, 5, 6]), (1720488555.303827, [], [1, 2, 3, 4, 5, 6])], - [ - (1720055240.779901, [], [1, 2, 3, 4, 5, 6]), - (1720485059.84637, [], [1, 2, 3, 4, 5, 6]), - (1720520102.630634, [], [1, 2, 3, 4, 5, 6]), - (1720591031.4354, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720570592.888394, [], [1, 2, 3, 4, 5, 6])], - [ - (1720059956.606064, [], [1, 2, 3, 4, 5, 6]), - (1720232781.82764, [], [1, 2, 3, 4, 5, 6]), - (1720489307.963369, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720466563.789269, [], [1, 2, 3, 4, 5, 6])], - [(1720120332.505828, [], [1, 2, 3, 4, 5, 6]), (1720501386.247192, [], [1, 2, 3, 4, 5, 6])], - [ - (1720045443.968104, [], [1, 2, 3, 4, 5, 6]), - (1720337612.000658, [], [1, 2, 3, 4, 5, 6]), - (1720484793.823359, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720240516.409323, [], [1, 2, 3, 4, 5, 6]), (1720508486.303913, [], [1, 2, 3, 4, 5, 6])], - [ - (1720056682.445295, [], [1, 2, 3, 4, 5, 6]), - (1720239570.480365, [], [1, 2, 3, 4, 5, 6]), - (1720399243.691516, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720065346.577694, [], [1, 2, 3, 4, 5, 6]), - (1720111179.563476, [], [1, 2, 3, 4, 5, 6]), - (1720152182.18393, [], [1, 2, 3, 4, 5, 6]), - (1720456368.150945, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720037842.027886, [], [1, 2, 3, 4, 5, 6])], - [(1720051512.155726, [], [1, 2, 3, 4, 5, 6]), (1720316085.436368, [], [1, 2, 3, 4, 5, 6])], - [ - (1720153922.872643, [], [1, 2, 3, 4, 5, 6]), - (1720316484.292604, [], [1, 2, 3, 4, 5, 6]), - (1720481626.562697, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720304528.044157, [], [1, 2, 3, 4, 5, 6]), (1720587171.914424, [], [1, 2, 3, 4, 5, 6])], - [ - (1719969690.052003, [], [1, 2, 3, 4, 5, 6]), - (1720098093.259497, [], [1, 2, 3, 4, 5, 6]), - (1720589467.401983, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720182994.851728, [], [1, 2, 3, 4, 5, 6]), (1720490206.204252, [], [1, 2, 3, 4, 5, 6])], - [(1720305269.133214, [], [1, 2, 3, 4, 5, 6]), (1720580679.401674, [], [1, 2, 3, 4, 5, 6])], - [(1720582113.001824, [], [1, 2, 3, 4, 5, 6])], - [ - (1719971867.373391, [], [1, 2, 3, 4, 5, 6]), - (1719971869.452767, [], [1, 2, 3, 4, 5, 6]), - (1719983561.418747, [], [1, 2, 3, 4, 5, 6]), - (1719983615.306689, [], [1, 2, 3, 4, 5, 6]), - (1719983617.371374, [], [1, 2, 3, 4, 5, 6]), - (1719983622.154397, [], [1, 2, 3, 4, 5, 6]), - (1719983624.239597, [], [1, 2, 3, 4, 5, 6]), - (1720057585.854293, [], [1, 2, 3, 4, 5, 6]), - (1720127843.991043, [], [1, 2, 3, 4, 5, 6]), - (1720127952.545227, [], [1, 2, 3, 4, 5, 6]), - (1720150451.197164, [], [1, 2, 3, 4, 5, 6]), - (1720150472.889245, [], [1, 2, 3, 4, 5, 6]), - (1720229579.372015, [], [1, 2, 3, 4, 5, 6]), - (1720229585.29839, [], [1, 2, 3, 4, 5, 6]), - (1720229587.33746, [], [1, 2, 3, 4, 5, 6]), - (1720272362.151724, [], [1, 2, 3, 4, 5, 6]), - (1720272395.494166, [], [1, 2, 3, 4, 5, 6]), - (1720272397.584197, [], [1, 2, 3, 4, 5, 6]), - (1720325287.360716, [], [1, 2, 3, 4, 5, 6]), - (1720325289.430457, [], [1, 2, 3, 4, 5, 6]), - (1720392144.674955, [], [1, 2, 3, 4, 5, 6]), - (1720392146.786158, [], [1, 2, 3, 4, 5, 6]), - (1720406690.885685, [], [1, 2, 3, 4, 5, 6]), - (1720406692.950513, [], [1, 2, 3, 4, 5, 6]), - (1720486441.134231, [], [1, 2, 3, 4, 5, 6]), - (1720486443.192435, [], [1, 2, 3, 4, 5, 6]), - (1720648828.296221, [], [1, 2, 3, 4, 5, 6]), - (1720648830.340132, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977053.236432, [], [1, 2, 3, 4, 5, 6])], - [(1720146886.388756, [], [1, 2, 3, 4, 5, 6])], - [(1720147721.983335, [], [1, 2, 3, 4, 5, 6]), (1720577319.095652, [], [1, 2, 3, 4, 5, 6])], - [(1720187232.833461, [], [1, 2, 3, 4, 5, 6])], - [(1720309745.334443, [], [1, 2, 3, 4, 5, 6]), (1720525020.981442, [], [1, 2, 3, 4, 5, 6])], - [(1719985270.896874, [], [1, 2, 3, 4, 5, 6]), (1720147203.361104, [], [1, 2, 3, 4, 5, 6])], - [(1719975189.590595, [], [1, 2, 3, 4, 5, 6])], - [ - (1720153681.561666, [], [1, 2, 3, 4, 5, 6]), - (1720315141.854012, [], [1, 2, 3, 4, 5, 6]), - (1720483759.06017, [], [1, 2, 3, 4, 5, 6]), - (1720632532.362134, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719969377.021113, [], [1, 2, 3, 4, 5, 6]), - (1719969547.865829, [], [1, 2, 3, 4, 5, 6]), - (1720050670.589639, [], [1, 2, 3, 4, 5, 6]), - (1720050713.412665, [], [1, 2, 3, 4, 5, 6]), - (1720139076.150907, [], [1, 2, 3, 4, 5, 6]), - (1720139087.933212, [], [1, 2, 3, 4, 5, 6]), - (1720139090.022598, [], [1, 2, 3, 4, 5, 6]), - (1720139092.090332, [], [1, 2, 3, 4, 5, 6]), - (1720148904.698605, [], [1, 2, 3, 4, 5, 6]), - (1720197454.202625, [], [1, 2, 3, 4, 5, 6]), - (1720197456.301898, [], [1, 2, 3, 4, 5, 6]), - (1720221957.937687, [], [1, 2, 3, 4, 5, 6]), - (1720222151.210074, [], [1, 2, 3, 4, 5, 6]), - (1720222153.281944, [], [1, 2, 3, 4, 5, 6]), - (1720231319.785278, [], [1, 2, 3, 4, 5, 6]), - (1720314287.823226, [], [1, 2, 3, 4, 5, 6]), - (1720314375.707773, [], [1, 2, 3, 4, 5, 6]), - (1720314377.787834, [], [1, 2, 3, 4, 5, 6]), - (1720331369.745063, [], [1, 2, 3, 4, 5, 6]), - (1720331582.949466, [], [1, 2, 3, 4, 5, 6]), - (1720331585.058912, [], [1, 2, 3, 4, 5, 6]), - (1720399235.526545, [], [1, 2, 3, 4, 5, 6]), - (1720399237.6268, [], [1, 2, 3, 4, 5, 6]), - (1720410762.341061, [], [1, 2, 3, 4, 5, 6]), - (1720410808.990309, [], [1, 2, 3, 4, 5, 6]), - (1720410811.040448, [], [1, 2, 3, 4, 5, 6]), - (1720493330.828194, [], [1, 2, 3, 4, 5, 6]), - (1720493516.887173, [], [1, 2, 3, 4, 5, 6]), - (1720501442.580123, [], [1, 2, 3, 4, 5, 6]), - (1720501548.316894, [], [1, 2, 3, 4, 5, 6]), - (1720501550.379738, [], [1, 2, 3, 4, 5, 6]), - (1720573012.279738, [], [1, 2, 3, 4, 5, 6]), - (1720573204.24471, [], [1, 2, 3, 4, 5, 6]), - (1720573206.359087, [], [1, 2, 3, 4, 5, 6]), - (1720573210.996145, [], [1, 2, 3, 4, 5, 6]), - (1720573213.096745, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719984464.146305, [], [1, 2, 3, 4, 5, 6])], - [(1719969484.575186, [], [1, 2, 3, 4, 5, 6])], - [(1719967098.321792, [], [1, 2, 3, 4, 5, 6]), (1720140304.171738, [], [1, 2, 3, 4, 5, 6])], - [ - (1720067679.407113, [], [1, 2, 3, 4, 5, 6]), - (1720240007.297001, [], [1, 2, 3, 4, 5, 6]), - (1720499615.946055, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719984745.989291, [], [1, 2, 3, 4, 5, 6]), - (1720088802.060799, [], [1, 2, 3, 4, 5, 6]), - (1720226330.102201, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720057325.702019, [], [1, 2, 3, 4, 5, 6]), (1720499465.567145, [], [1, 2, 3, 4, 5, 6])], - [ - (1720055478.668518, [], [1, 2, 3, 4, 5, 6]), - (1720055619.422527, [], [1, 2, 3, 4, 5, 6]), - (1720138025.392906, [], [1, 2, 3, 4, 5, 6]), - (1720138074.32289, [], [1, 2, 3, 4, 5, 6]), - (1720232045.90559, [], [1, 2, 3, 4, 5, 6]), - (1720232073.337701, [], [1, 2, 3, 4, 5, 6]), - (1720278094.793407, [], [1, 2, 3, 4, 5, 6]), - (1720278096.912409, [], [1, 2, 3, 4, 5, 6]), - (1720278099.569789, [], [1, 2, 3, 4, 5, 6]), - (1720278101.660519, [], [1, 2, 3, 4, 5, 6]), - (1720324663.973123, [], [1, 2, 3, 4, 5, 6]), - (1720324666.034118, [], [1, 2, 3, 4, 5, 6]), - (1720412864.0991, [], [1, 2, 3, 4, 5, 6]), - (1720412932.896312, [], [1, 2, 3, 4, 5, 6]), - (1720412934.95735, [], [1, 2, 3, 4, 5, 6]), - (1720493768.204791, [], [1, 2, 3, 4, 5, 6]), - (1720493848.668367, [], [1, 2, 3, 4, 5, 6]), - (1720493850.800293, [], [1, 2, 3, 4, 5, 6]), - (1720493853.855696, [], [1, 2, 3, 4, 5, 6]), - (1720578407.565863, [], [1, 2, 3, 4, 5, 6]), - (1720578455.012928, [], [1, 2, 3, 4, 5, 6]), - (1720578457.12311, [], [1, 2, 3, 4, 5, 6]), - (1720592507.954368, [], [1, 2, 3, 4, 5, 6]), - (1720592695.674207, [], [1, 2, 3, 4, 5, 6]), - (1720592697.763035, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720448820.538088, [], [1, 2, 3, 4, 5, 6]), - (1720448848.354821, [], [1, 2, 3, 4, 5, 6]), - (1720448968.980221, [], [1, 2, 3, 4, 5, 6]), - (1720449109.647373, [], [1, 2, 3, 4, 5, 6]), - (1720449132.605916, [], [1, 2, 3, 4, 5, 6]), - (1720449141.226924, [], [1, 2, 3, 4, 5, 6]), - (1720449174.132961, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720143295.563285, [], [1, 2, 3, 4, 5, 6])], - [ - (1720009875.184202, [], [1, 2, 3, 4, 5, 6]), - (1720064301.403426, [], [1, 2, 3, 4, 5, 6]), - (1720221459.433168, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720316122.630709, [], [1, 2, 3, 4, 5, 6]), (1720625396.811387, [], [1, 2, 3, 4, 5, 6])], - [(1720064525.079458, [], [1, 2, 3, 4, 5, 6])], - [(1720600790.059805, [], [1, 2, 3, 4, 5, 6])], - [(1720053513.239524, [], [1, 2, 3, 4, 5, 6]), (1720533559.490134, [], [1, 2, 3, 4, 5, 6])], - [(1720222657.803241, [], [1, 2, 3, 4, 5, 6])], - [ - (1719971419.792625, [], [1, 2, 3, 4, 5, 6]), - (1720239049.653382, [], [1, 2, 3, 4, 5, 6]), - (1720497253.487835, [], [1, 2, 3, 4, 5, 6]), - (1720571009.60795, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719978213.57048, [], [1, 2, 3, 4, 5, 6]), - (1719978402.543586, [], [1, 2, 3, 4, 5, 6]), - (1720067921.564313, [], [1, 2, 3, 4, 5, 6]), - (1720068031.2973, [], [1, 2, 3, 4, 5, 6]), - (1720068033.364045, [], [1, 2, 3, 4, 5, 6]), - (1720076693.193638, [], [1, 2, 3, 4, 5, 6]), - (1720076695.234922, [], [1, 2, 3, 4, 5, 6]), - (1720088372.082518, [], [1, 2, 3, 4, 5, 6]), - (1720088448.747115, [], [1, 2, 3, 4, 5, 6]), - (1720222636.476764, [], [1, 2, 3, 4, 5, 6]), - (1720222701.214913, [], [1, 2, 3, 4, 5, 6]), - (1720311136.481341, [], [1, 2, 3, 4, 5, 6]), - (1720311279.356667, [], [1, 2, 3, 4, 5, 6]), - (1720311281.435353, [], [1, 2, 3, 4, 5, 6]), - (1720321937.516249, [], [1, 2, 3, 4, 5, 6]), - (1720321977.750869, [], [1, 2, 3, 4, 5, 6]), - (1720321979.826956, [], [1, 2, 3, 4, 5, 6]), - (1720321983.309368, [], [1, 2, 3, 4, 5, 6]), - (1720417820.177018, [], [1, 2, 3, 4, 5, 6]), - (1720417888.907443, [], [1, 2, 3, 4, 5, 6]), - (1720482544.485269, [], [1, 2, 3, 4, 5, 6]), - (1720482650.874077, [], [1, 2, 3, 4, 5, 6]), - (1720571012.586842, [], [1, 2, 3, 4, 5, 6]), - (1720571014.653099, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720067135.000485, [], [1, 2, 3, 4, 5, 6]), - (1720226886.323383, [], [1, 2, 3, 4, 5, 6]), - (1720626810.190995, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720021468.494681, [], [1, 2, 3, 4, 5, 6]), (1720244311.296556, [], [1, 2, 3, 4, 5, 6])], - [ - (1720054497.052088, [], [1, 2, 3, 4, 5, 6]), - (1720315797.04068, [], [1, 2, 3, 4, 5, 6]), - (1720396623.976121, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719970439.050635, [], [1, 2, 3, 4, 5, 6]), (1720411294.606462, [], [1, 2, 3, 4, 5, 6])], - [ - (1720047660.240807, [], [1, 2, 3, 4, 5, 6]), - (1720209425.126479, [], [1, 2, 3, 4, 5, 6]), - (1720417042.301423, [], [1, 2, 3, 4, 5, 6]), - (1720579466.836909, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720068666.058135, [], [1, 2, 3, 4, 5, 6]), - (1720224717.712974, [], [1, 2, 3, 4, 5, 6]), - (1720313644.184984, [], [1, 2, 3, 4, 5, 6]), - (1720417247.572309, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720217112.012918, [], [1, 2, 3, 4, 5, 6])], - [(1720228893.793094, [], [1, 2, 3, 4, 5, 6])], - [ - (1719965114.583168, [], [1, 2, 3, 4, 5, 6]), - (1720221700.128257, [], [1, 2, 3, 4, 5, 6]), - (1720359492.65181, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720149938.452021, [], [1, 2, 3, 4, 5, 6]), - (1720150083.518978, [], [1, 2, 3, 4, 5, 6]), - (1720150100.711862, [], [1, 2, 3, 4, 5, 6]), - (1720403516.136956, [], [1, 2, 3, 4, 5, 6]), - (1720403602.399166, [], [1, 2, 3, 4, 5, 6]), - (1720403688.061721, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720016151.530651, [], [1, 2, 3, 4, 5, 6]), - (1720126052.51206, [], [1, 2, 3, 4, 5, 6]), - (1720243360.967974, [], [1, 2, 3, 4, 5, 6]), - (1720567481.805169, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720259903.388453, [], [1, 2, 3, 4, 5, 6]), (1720495071.607118, [], [1, 2, 3, 4, 5, 6])], - [ - (1719978731.351246, [], [1, 2, 3, 4, 5, 6]), - (1720142275.008236, [], [1, 2, 3, 4, 5, 6]), - (1720225627.748133, [], [1, 2, 3, 4, 5, 6]), - (1720599835.060544, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720308817.017884, [], [1, 2, 3, 4, 5, 6]), (1720500376.721695, [], [1, 2, 3, 4, 5, 6])], - [ - (1720062080.162523, [], [1, 2, 3, 4, 5, 6]), - (1720424051.051867, [], [1, 2, 3, 4, 5, 6]), - (1720577193.657241, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720226358.301934, [], [1, 2, 3, 4, 5, 6]), (1720611516.599998, [], [1, 2, 3, 4, 5, 6])], - [(1720142831.087971, [], [1, 2, 3, 4, 5, 6]), (1720568727.59182, [], [1, 2, 3, 4, 5, 6])], - [(1720045127.801767, [], [1, 2, 3, 4, 5, 6])], - [(1720598254.557545, [], [1, 2, 3, 4, 5, 6])], - [(1720230498.737196, [], [1, 2, 3, 4, 5, 6]), (1720502519.921733, [], [1, 2, 3, 4, 5, 6])], - [(1720149819.132452, [], [1, 2, 3, 4, 5, 6]), (1720317818.669453, [], [1, 2, 3, 4, 5, 6])], - [(1719965630.184525, [], [1, 2, 3, 4, 5, 6]), (1720566194.006106, [], [1, 2, 3, 4, 5, 6])], - [(1719996710.23806, [], [1, 2, 3, 4, 5, 6])], - [(1720053587.04154, [], [1, 2, 3, 4, 5, 6]), (1720476400.319672, [], [1, 2, 3, 4, 5, 6])], - [(1720238998.499612, [], [1, 2, 3, 4, 5, 6])], - [(1720049964.339669, [], [1, 2, 3, 4, 5, 6]), (1720503256.459045, [], [1, 2, 3, 4, 5, 6])], - [(1720629914.75266, [], [1, 2, 3, 4, 5, 6])], - [ - (1720067406.552276, [], [1, 2, 3, 4, 5, 6]), - (1720192823.078475, [], [1, 2, 3, 4, 5, 6]), - (1720615636.068682, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720050726.320669, [], [1, 2, 3, 4, 5, 6]), - (1720159164.117987, [], [1, 2, 3, 4, 5, 6]), - (1720583837.972687, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720470505.483407, [], [1, 2, 3, 4, 5, 6]), (1720589293.330858, [], [1, 2, 3, 4, 5, 6])], - [ - (1719990309.924021, [], [1, 2, 3, 4, 5, 6]), - (1720242385.881249, [], [1, 2, 3, 4, 5, 6]), - (1720648573.041044, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720059240.88106, [], [1, 2, 3, 4, 5, 6]), (1720486550.385795, [], [1, 2, 3, 4, 5, 6])], - [(1720232277.114726, [], [1, 2, 3, 4, 5, 6])], - [(1720156360.413945, [], [1, 2, 3, 4, 5, 6]), (1720415380.907597, [], [1, 2, 3, 4, 5, 6])], - [(1720143721.130937, [], [1, 2, 3, 4, 5, 6])], - [(1720093040.94431, [], [1, 2, 3, 4, 5, 6]), (1720230385.831757, [], [1, 2, 3, 4, 5, 6])], - [(1720313919.101562, [], [1, 2, 3, 4, 5, 6]), (1720600894.542752, [], [1, 2, 3, 4, 5, 6])], - [(1720008883.059792, [], [1, 2, 3, 4, 5, 6]), (1720151981.800615, [], [1, 2, 3, 4, 5, 6])], - [(1720583883.771582, [], [1, 2, 3, 4, 5, 6])], - [(1720054595.476172, [], [1, 2, 3, 4, 5, 6]), (1720494101.96425, [], [1, 2, 3, 4, 5, 6])], - [ - (1719975987.869421, [], [1, 2, 3, 4, 5, 6]), - (1720072012.445937, [], [1, 2, 3, 4, 5, 6]), - (1720141541.892965, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974700.775073, [], [1, 2, 3, 4, 5, 6]), - (1719974810.784479, [], [1, 2, 3, 4, 5, 6]), - (1720022010.687673, [], [1, 2, 3, 4, 5, 6]), - (1720022125.15125, [], [1, 2, 3, 4, 5, 6]), - (1720022127.183082, [], [1, 2, 3, 4, 5, 6]), - (1720022127.850327, [], [1, 2, 3, 4, 5, 6]), - (1720022129.972437, [], [1, 2, 3, 4, 5, 6]), - (1720149346.519881, [], [1, 2, 3, 4, 5, 6]), - (1720149423.39517, [], [1, 2, 3, 4, 5, 6]), - (1720232515.945385, [], [1, 2, 3, 4, 5, 6]), - (1720232642.031851, [], [1, 2, 3, 4, 5, 6]), - (1720232644.151326, [], [1, 2, 3, 4, 5, 6]), - (1720232649.102724, [], [1, 2, 3, 4, 5, 6]), - (1720232651.213687, [], [1, 2, 3, 4, 5, 6]), - (1720291284.378849, [], [1, 2, 3, 4, 5, 6]), - (1720291307.651917, [], [1, 2, 3, 4, 5, 6]), - (1720317724.65539, [], [1, 2, 3, 4, 5, 6]), - (1720317962.176994, [], [1, 2, 3, 4, 5, 6]), - (1720317962.221761, [], [1, 2, 3, 4, 5, 6]), - (1720317967.870483, [], [1, 2, 3, 4, 5, 6]), - (1720416284.403485, [], [1, 2, 3, 4, 5, 6]), - (1720416286.45094, [], [1, 2, 3, 4, 5, 6]), - (1720446964.44037, [], [1, 2, 3, 4, 5, 6]), - (1720447111.491786, [], [1, 2, 3, 4, 5, 6]), - (1720447113.551591, [], [1, 2, 3, 4, 5, 6]), - (1720500857.609857, [], [1, 2, 3, 4, 5, 6]), - (1720500933.241251, [], [1, 2, 3, 4, 5, 6]), - (1720500935.342693, [], [1, 2, 3, 4, 5, 6]), - (1720550391.631024, [], [1, 2, 3, 4, 5, 6]), - (1720550393.677097, [], [1, 2, 3, 4, 5, 6]), - (1720571962.115275, [], [1, 2, 3, 4, 5, 6]), - (1720571964.156322, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720300973.659698, [], [1, 2, 3, 4, 5, 6]), (1720502088.420309, [], [1, 2, 3, 4, 5, 6])], - [ - (1720226060.114355, [], [1, 2, 3, 4, 5, 6]), - (1720367668.242413, [], [1, 2, 3, 4, 5, 6]), - (1720580879.469873, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720148122.993839, [], [1, 2, 3, 4, 5, 6]), - (1720283848.988921, [], [1, 2, 3, 4, 5, 6]), - (1720392902.670008, [], [1, 2, 3, 4, 5, 6]), - (1720547569.939146, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720164561.277691, [], [1, 2, 3, 4, 5, 6]), (1720322322.293618, [], [1, 2, 3, 4, 5, 6])], - [(1720394391.029382, [], [1, 2, 3, 4, 5, 6])], - [(1720578227.91725, [], [1, 2, 3, 4, 5, 6])], - [(1720427348.104988, [], [1, 2, 3, 4, 5, 6]), (1720586312.438776, [], [1, 2, 3, 4, 5, 6])], - [ - (1719967279.972433, [], [1, 2, 3, 4, 5, 6]), - (1719967282.055508, [], [1, 2, 3, 4, 5, 6]), - (1719986090.097845, [], [1, 2, 3, 4, 5, 6]), - (1719986173.00659, [], [1, 2, 3, 4, 5, 6]), - (1719986175.082864, [], [1, 2, 3, 4, 5, 6]), - (1720034526.875582, [], [1, 2, 3, 4, 5, 6]), - (1720061201.725715, [], [1, 2, 3, 4, 5, 6]), - (1720061294.240057, [], [1, 2, 3, 4, 5, 6]), - (1720061296.35589, [], [1, 2, 3, 4, 5, 6]), - (1720155141.396653, [], [1, 2, 3, 4, 5, 6]), - (1720155143.510508, [], [1, 2, 3, 4, 5, 6]), - (1720155145.301155, [], [1, 2, 3, 4, 5, 6]), - (1720155147.393972, [], [1, 2, 3, 4, 5, 6]), - (1720231098.024705, [], [1, 2, 3, 4, 5, 6]), - (1720231317.54759, [], [1, 2, 3, 4, 5, 6]), - (1720231319.611985, [], [1, 2, 3, 4, 5, 6]), - (1720271983.621164, [], [1, 2, 3, 4, 5, 6]), - (1720271985.710974, [], [1, 2, 3, 4, 5, 6]), - (1720316981.40392, [], [1, 2, 3, 4, 5, 6]), - (1720317019.941522, [], [1, 2, 3, 4, 5, 6]), - (1720317022.040965, [], [1, 2, 3, 4, 5, 6]), - (1720411936.226228, [], [1, 2, 3, 4, 5, 6]), - (1720411963.208146, [], [1, 2, 3, 4, 5, 6]), - (1720479757.589657, [], [1, 2, 3, 4, 5, 6]), - (1720479839.302922, [], [1, 2, 3, 4, 5, 6]), - (1720582109.835415, [], [1, 2, 3, 4, 5, 6]), - (1720582111.914294, [], [1, 2, 3, 4, 5, 6]), - (1720652093.707438, [], [1, 2, 3, 4, 5, 6]), - (1720652211.598303, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720579951.356488, [], [1, 2, 3, 4, 5, 6])], - [(1720593973.655643, [], [1, 2, 3, 4, 5, 6])], - [ - (1720061475.003195, [], [1, 2, 3, 4, 5, 6]), - (1720270392.101123, [], [1, 2, 3, 4, 5, 6]), - (1720415797.057544, [], [1, 2, 3, 4, 5, 6]), - (1720574029.592383, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719987865.032004, [], [1, 2, 3, 4, 5, 6]), (1720212776.214811, [], [1, 2, 3, 4, 5, 6])], - [(1720315089.869542, [], [1, 2, 3, 4, 5, 6]), (1720578088.622431, [], [1, 2, 3, 4, 5, 6])], - [(1720575422.335555, [], [1, 2, 3, 4, 5, 6])], - [(1720329438.482756, [], [1, 2, 3, 4, 5, 6]), (1720443842.432414, [], [1, 2, 3, 4, 5, 6])], - [ - (1720135846.308239, [], [1, 2, 3, 4, 5, 6]), - (1720221161.535587, [], [1, 2, 3, 4, 5, 6]), - (1720326226.738859, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719977789.721113, [], [1, 2, 3, 4, 5, 6]), - (1719977899.031956, [], [1, 2, 3, 4, 5, 6]), - (1719977901.119465, [], [1, 2, 3, 4, 5, 6]), - (1719982587.985388, [], [1, 2, 3, 4, 5, 6]), - (1719982666.211377, [], [1, 2, 3, 4, 5, 6]), - (1719982668.29279, [], [1, 2, 3, 4, 5, 6]), - (1719982672.56956, [], [1, 2, 3, 4, 5, 6]), - (1720063592.708606, [], [1, 2, 3, 4, 5, 6]), - (1720063594.776009, [], [1, 2, 3, 4, 5, 6]), - (1720145103.906614, [], [1, 2, 3, 4, 5, 6]), - (1720145165.665926, [], [1, 2, 3, 4, 5, 6]), - (1720157026.459569, [], [1, 2, 3, 4, 5, 6]), - (1720223512.011646, [], [1, 2, 3, 4, 5, 6]), - (1720223586.453989, [], [1, 2, 3, 4, 5, 6]), - (1720223588.535794, [], [1, 2, 3, 4, 5, 6]), - (1720329405.565358, [], [1, 2, 3, 4, 5, 6]), - (1720398313.307695, [], [1, 2, 3, 4, 5, 6]), - (1720398429.724071, [], [1, 2, 3, 4, 5, 6]), - (1720414381.775047, [], [1, 2, 3, 4, 5, 6]), - (1720446240.471098, [], [1, 2, 3, 4, 5, 6]), - (1720481889.793923, [], [1, 2, 3, 4, 5, 6]), - (1720481891.93036, [], [1, 2, 3, 4, 5, 6]), - (1720489136.015971, [], [1, 2, 3, 4, 5, 6]), - (1720489247.728734, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720318482.752639, [], [1, 2, 3, 4, 5, 6])], - [ - (1720242162.48487, [], [1, 2, 3, 4, 5, 6]), - (1720503535.294123, [], [1, 2, 3, 4, 5, 6]), - (1720590538.582039, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720148407.104121, [], [1, 2, 3, 4, 5, 6])], - [(1720154168.367205, [], [1, 2, 3, 4, 5, 6]), (1720568213.544423, [], [1, 2, 3, 4, 5, 6])], - [ - (1720069001.717509, [], [1, 2, 3, 4, 5, 6]), - (1720346135.538471, [], [1, 2, 3, 4, 5, 6]), - (1720489854.284499, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719967260.706099, [], [1, 2, 3, 4, 5, 6]), - (1720082538.484733, [], [1, 2, 3, 4, 5, 6]), - (1720240732.567635, [], [1, 2, 3, 4, 5, 6]), - (1720395713.187024, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719968640.279026, [], [1, 2, 3, 4, 5, 6]), - (1720058387.048155, [], [1, 2, 3, 4, 5, 6]), - (1720240163.514327, [], [1, 2, 3, 4, 5, 6]), - (1720391336.792179, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720310285.653948, [], [1, 2, 3, 4, 5, 6]), (1720589147.207321, [], [1, 2, 3, 4, 5, 6])], - [(1719973140.021275, [], [1, 2, 3, 4, 5, 6]), (1720504055.006021, [], [1, 2, 3, 4, 5, 6])], - [(1720115792.85023, [], [1, 2, 3, 4, 5, 6])], - [ - (1720140689.444004, [], [1, 2, 3, 4, 5, 6]), - (1720312169.980048, [], [1, 2, 3, 4, 5, 6]), - (1720399894.527727, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720316227.642169, [], [1, 2, 3, 4, 5, 6]), (1720484121.740556, [], [1, 2, 3, 4, 5, 6])], - [ - (1720150629.632571, [], [1, 2, 3, 4, 5, 6]), - (1720312593.72112, [], [1, 2, 3, 4, 5, 6]), - (1720584121.246833, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719966806.196729, [], [1, 2, 3, 4, 5, 6]), (1720492831.262792, [], [1, 2, 3, 4, 5, 6])], - [ - (1720069584.25825, [], [1, 2, 3, 4, 5, 6]), - (1720233172.76065, [], [1, 2, 3, 4, 5, 6]), - (1720317363.164219, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720227600.733956, [], [1, 2, 3, 4, 5, 6]), - (1720227600.784387, [], [1, 2, 3, 4, 5, 6]), - (1720227605.27419, [], [1, 2, 3, 4, 5, 6]), - (1720269710.791405, [], [1, 2, 3, 4, 5, 6]), - (1720269759.332462, [], [1, 2, 3, 4, 5, 6]), - (1720326344.424672, [], [1, 2, 3, 4, 5, 6]), - (1720369614.287387, [], [1, 2, 3, 4, 5, 6]), - (1720369719.27491, [], [1, 2, 3, 4, 5, 6]), - (1720369719.331218, [], [1, 2, 3, 4, 5, 6]), - (1720369721.899004, [], [1, 2, 3, 4, 5, 6]), - (1720385493.685201, [], [1, 2, 3, 4, 5, 6]), - (1720385551.219825, [], [1, 2, 3, 4, 5, 6]), - (1720385553.316418, [], [1, 2, 3, 4, 5, 6]), - (1720450115.39061, [], [1, 2, 3, 4, 5, 6]), - (1720450117.502598, [], [1, 2, 3, 4, 5, 6]), - (1720450118.78177, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719969800.978378, [], [1, 2, 3, 4, 5, 6]), - (1720222415.35262, [], [1, 2, 3, 4, 5, 6]), - (1720434706.74629, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720237451.24597, [], [1, 2, 3, 4, 5, 6]), (1720585495.150654, [], [1, 2, 3, 4, 5, 6])], - [(1719970937.04025, [], [1, 2, 3, 4, 5, 6])], - [ - (1719983075.420902, [], [1, 2, 3, 4, 5, 6]), - (1720313367.078665, [], [1, 2, 3, 4, 5, 6]), - (1720413122.113225, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720155749.238687, [], [1, 2, 3, 4, 5, 6]), (1720491353.243799, [], [1, 2, 3, 4, 5, 6])], - [(1720060021.000595, [], [1, 2, 3, 4, 5, 6])], - [(1719988378.536367, [], [1, 2, 3, 4, 5, 6]), (1720228662.183092, [], [1, 2, 3, 4, 5, 6])], - [(1719981886.782157, [], [1, 2, 3, 4, 5, 6]), (1720156878.496962, [], [1, 2, 3, 4, 5, 6])], - [(1720582313.689559, [], [1, 2, 3, 4, 5, 6])], - [(1720232302.477057, [], [1, 2, 3, 4, 5, 6]), (1720493756.958556, [], [1, 2, 3, 4, 5, 6])], - [(1720295778.241704, [], [1, 2, 3, 4, 5, 6])], - [(1720021503.203052, [], [1, 2, 3, 4, 5, 6]), (1720325452.491454, [], [1, 2, 3, 4, 5, 6])], - [(1720527219.478404, [], [1, 2, 3, 4, 5, 6]), (1720567646.306507, [], [1, 2, 3, 4, 5, 6])], - [(1720223792.29193, [], [1, 2, 3, 4, 5, 6])], - [ - (1720006636.772706, [], [1, 2, 3, 4, 5, 6]), - (1720006795.60427, [], [1, 2, 3, 4, 5, 6]), - (1720006845.799981, [], [1, 2, 3, 4, 5, 6]), - (1720007022.741945, [], [1, 2, 3, 4, 5, 6]), - (1720007095.581047, [], [1, 2, 3, 4, 5, 6]), - (1720007134.850115, [], [1, 2, 3, 4, 5, 6]), - (1720025117.762503, [], [1, 2, 3, 4, 5, 6]), - (1720025308.512649, [], [1, 2, 3, 4, 5, 6]), - (1720025310.568037, [], [1, 2, 3, 4, 5, 6]), - (1720052547.163003, [], [1, 2, 3, 4, 5, 6]), - (1720052600.03312, [], [1, 2, 3, 4, 5, 6]), - (1720068046.902248, [], [1, 2, 3, 4, 5, 6]), - (1720068213.189912, [], [1, 2, 3, 4, 5, 6]), - (1720144711.311281, [], [1, 2, 3, 4, 5, 6]), - (1720144713.407177, [], [1, 2, 3, 4, 5, 6]), - (1720222638.332245, [], [1, 2, 3, 4, 5, 6]), - (1720222640.418838, [], [1, 2, 3, 4, 5, 6]), - (1720242141.813366, [], [1, 2, 3, 4, 5, 6]), - (1720242245.921587, [], [1, 2, 3, 4, 5, 6]), - (1720242248.011768, [], [1, 2, 3, 4, 5, 6]), - (1720333146.03005, [], [1, 2, 3, 4, 5, 6]), - (1720333287.562561, [], [1, 2, 3, 4, 5, 6]), - (1720333289.592652, [], [1, 2, 3, 4, 5, 6]), - (1720333292.319879, [], [1, 2, 3, 4, 5, 6]), - (1720333294.386109, [], [1, 2, 3, 4, 5, 6]), - (1720396984.211837, [], [1, 2, 3, 4, 5, 6]), - (1720397094.401782, [], [1, 2, 3, 4, 5, 6]), - (1720486134.144443, [], [1, 2, 3, 4, 5, 6]), - (1720486136.211044, [], [1, 2, 3, 4, 5, 6]), - (1720486140.873481, [], [1, 2, 3, 4, 5, 6]), - (1720486142.970428, [], [1, 2, 3, 4, 5, 6]), - (1720497754.706526, [], [1, 2, 3, 4, 5, 6]), - (1720497979.155047, [], [1, 2, 3, 4, 5, 6]), - (1720531991.462042, [], [1, 2, 3, 4, 5, 6]), - (1720532199.030662, [], [1, 2, 3, 4, 5, 6]), - (1720588796.771517, [], [1, 2, 3, 4, 5, 6]), - (1720588842.077879, [], [1, 2, 3, 4, 5, 6]), - (1720588844.116306, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720239926.764196, [], [1, 2, 3, 4, 5, 6])], - [(1720395045.1902, [], [1, 2, 3, 4, 5, 6])], - [(1720431147.297621, [], [1, 2, 3, 4, 5, 6])], - [(1720240748.713179, [], [1, 2, 3, 4, 5, 6])], - [(1719972432.742571, [], [1, 2, 3, 4, 5, 6])], - [(1720410198.607466, [], [1, 2, 3, 4, 5, 6]), (1720566548.549011, [], [1, 2, 3, 4, 5, 6])], - [(1720455428.865155, [], [1, 2, 3, 4, 5, 6])], - [(1720498325.755933, [], [1, 2, 3, 4, 5, 6])], - [ - (1719983684.033908, [], [1, 2, 3, 4, 5, 6]), - (1720319741.991515, [], [1, 2, 3, 4, 5, 6]), - (1720414800.645761, [], [1, 2, 3, 4, 5, 6]), - (1720484979.12583, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720134283.600008, [], [1, 2, 3, 4, 5, 6])], - [(1720409485.01654, [], [1, 2, 3, 4, 5, 6])], - [ - (1719981074.661088, [], [1, 2, 3, 4, 5, 6]), - (1720143880.41593, [], [1, 2, 3, 4, 5, 6]), - (1720229983.175788, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060903.203334, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968419.743912, [], [1, 2, 3, 4, 5, 6]), - (1719968490.438903, [], [1, 2, 3, 4, 5, 6]), - (1719968620.857174, [], [1, 2, 3, 4, 5, 6]), - (1720498112.351156, [], [1, 2, 3, 4, 5, 6]), - (1720498358.36836, [], [1, 2, 3, 4, 5, 6]), - (1720498468.250047, [], [1, 2, 3, 4, 5, 6]), - (1720574778.111823, [], [1, 2, 3, 4, 5, 6]), - (1720574806.5479, [], [1, 2, 3, 4, 5, 6]), - (1720574917.425735, [], [1, 2, 3, 4, 5, 6]), - (1720574933.603291, [], [1, 2, 3, 4, 5, 6]), - (1720575020.164914, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720406407.483318, [], [1, 2, 3, 4, 5, 6])], - [(1720412099.352018, [], [1, 2, 3, 4, 5, 6]), (1720498223.084881, [], [1, 2, 3, 4, 5, 6])], - [ - (1719979024.598321, [], [1, 2, 3, 4, 5, 6]), - (1720114791.984992, [], [1, 2, 3, 4, 5, 6]), - (1720241390.157269, [], [1, 2, 3, 4, 5, 6]), - (1720500283.345509, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720569522.382331, [], [1, 2, 3, 4, 5, 6])], - [(1720146840.111051, [], [1, 2, 3, 4, 5, 6]), (1720287268.372643, [], [1, 2, 3, 4, 5, 6])], - [(1720583508.926048, [], [1, 2, 3, 4, 5, 6])], - [ - (1720229146.528014, [], [1, 2, 3, 4, 5, 6]), - (1720229340.131801, [], [1, 2, 3, 4, 5, 6]), - (1720229424.480475, [], [1, 2, 3, 4, 5, 6]), - (1720229565.859999, [], [1, 2, 3, 4, 5, 6]), - (1720229567.783491, [], [1, 2, 3, 4, 5, 6]), - (1720229693.297904, [], [1, 2, 3, 4, 5, 6]), - (1720229755.453165, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720098291.146186, [], [1, 2, 3, 4, 5, 6])], - [(1719983104.788269, [], [1, 2, 3, 4, 5, 6]), (1720070626.816099, [], [1, 2, 3, 4, 5, 6])], - [ - (1720226820.995006, [], [1, 2, 3, 4, 5, 6]), - (1720316639.892049, [], [1, 2, 3, 4, 5, 6]), - (1720589368.875624, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720070877.576019, [], [1, 2, 3, 4, 5, 6]), (1720234703.959519, [], [1, 2, 3, 4, 5, 6])], - [ - (1719978870.060134, [], [1, 2, 3, 4, 5, 6]), - (1720137971.413991, [], [1, 2, 3, 4, 5, 6]), - (1720491059.303159, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719995043.481796, [], [1, 2, 3, 4, 5, 6]), (1720148819.805573, [], [1, 2, 3, 4, 5, 6])], - [ - (1720052005.359573, [], [1, 2, 3, 4, 5, 6]), - (1720052127.565063, [], [1, 2, 3, 4, 5, 6]), - (1720052129.679258, [], [1, 2, 3, 4, 5, 6]), - (1720064915.795875, [], [1, 2, 3, 4, 5, 6]), - (1720064917.840723, [], [1, 2, 3, 4, 5, 6]), - (1720064919.250429, [], [1, 2, 3, 4, 5, 6]), - (1720140563.359858, [], [1, 2, 3, 4, 5, 6]), - (1720140686.221967, [], [1, 2, 3, 4, 5, 6]), - (1720147133.126896, [], [1, 2, 3, 4, 5, 6]), - (1720154606.237768, [], [1, 2, 3, 4, 5, 6]), - (1720208312.107821, [], [1, 2, 3, 4, 5, 6]), - (1720208397.77235, [], [1, 2, 3, 4, 5, 6]), - (1720208399.88578, [], [1, 2, 3, 4, 5, 6]), - (1720226692.740751, [], [1, 2, 3, 4, 5, 6]), - (1720226809.874422, [], [1, 2, 3, 4, 5, 6]), - (1720226811.929607, [], [1, 2, 3, 4, 5, 6]), - (1720320735.680282, [], [1, 2, 3, 4, 5, 6]), - (1720320737.781583, [], [1, 2, 3, 4, 5, 6]), - (1720394544.101953, [], [1, 2, 3, 4, 5, 6]), - (1720394546.228449, [], [1, 2, 3, 4, 5, 6]), - (1720411628.159882, [], [1, 2, 3, 4, 5, 6]), - (1720411765.678009, [], [1, 2, 3, 4, 5, 6]), - (1720411765.737071, [], [1, 2, 3, 4, 5, 6]), - (1720411771.063593, [], [1, 2, 3, 4, 5, 6]), - (1720493021.815332, [], [1, 2, 3, 4, 5, 6]), - (1720493023.89141, [], [1, 2, 3, 4, 5, 6]), - (1720547092.818141, [], [1, 2, 3, 4, 5, 6]), - (1720547133.337079, [], [1, 2, 3, 4, 5, 6]), - (1720566405.934125, [], [1, 2, 3, 4, 5, 6]), - (1720566407.979963, [], [1, 2, 3, 4, 5, 6]), - (1720592934.864349, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720407281.391395, [], [1, 2, 3, 4, 5, 6]), (1720578489.911262, [], [1, 2, 3, 4, 5, 6])], - [(1720393905.799101, [], [1, 2, 3, 4, 5, 6])], - [ - (1719965431.440319, [], [1, 2, 3, 4, 5, 6]), - (1719965547.770505, [], [1, 2, 3, 4, 5, 6]), - (1719965549.880668, [], [1, 2, 3, 4, 5, 6]), - (1720010279.644796, [], [1, 2, 3, 4, 5, 6]), - (1720010481.117481, [], [1, 2, 3, 4, 5, 6]), - (1720060297.061777, [], [1, 2, 3, 4, 5, 6]), - (1720060299.106745, [], [1, 2, 3, 4, 5, 6]), - (1720072795.790373, [], [1, 2, 3, 4, 5, 6]), - (1720072933.175213, [], [1, 2, 3, 4, 5, 6]), - (1720138923.382269, [], [1, 2, 3, 4, 5, 6]), - (1720138952.892452, [], [1, 2, 3, 4, 5, 6]), - (1720138954.952138, [], [1, 2, 3, 4, 5, 6]), - (1720243737.055635, [], [1, 2, 3, 4, 5, 6]), - (1720243742.725476, [], [1, 2, 3, 4, 5, 6]), - (1720243744.812736, [], [1, 2, 3, 4, 5, 6]), - (1720278868.092914, [], [1, 2, 3, 4, 5, 6]), - (1720278981.120539, [], [1, 2, 3, 4, 5, 6]), - (1720278983.221413, [], [1, 2, 3, 4, 5, 6]), - (1720312851.319112, [], [1, 2, 3, 4, 5, 6]), - (1720312961.59678, [], [1, 2, 3, 4, 5, 6]), - (1720312963.701002, [], [1, 2, 3, 4, 5, 6]), - (1720401167.589016, [], [1, 2, 3, 4, 5, 6]), - (1720401192.232905, [], [1, 2, 3, 4, 5, 6]), - (1720488671.153932, [], [1, 2, 3, 4, 5, 6]), - (1720488673.262556, [], [1, 2, 3, 4, 5, 6]), - (1720498148.914747, [], [1, 2, 3, 4, 5, 6]), - (1720498151.01221, [], [1, 2, 3, 4, 5, 6]), - (1720585902.00157, [], [1, 2, 3, 4, 5, 6]), - (1720585904.068243, [], [1, 2, 3, 4, 5, 6]), - (1720627230.183177, [], [1, 2, 3, 4, 5, 6]), - (1720627251.343451, [], [1, 2, 3, 4, 5, 6]), - (1720627253.395817, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720049050.269443, [], [1, 2, 3, 4, 5, 6])], - [(1720406587.77676, [], [1, 2, 3, 4, 5, 6])], - [ - (1720201120.604139, [], [1, 2, 3, 4, 5, 6]), - (1720237348.670203, [], [1, 2, 3, 4, 5, 6]), - (1720503188.882528, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720137961.069782, [], [1, 2, 3, 4, 5, 6]), (1720233994.333193, [], [1, 2, 3, 4, 5, 6])], - [(1720148673.115174, [], [1, 2, 3, 4, 5, 6])], - [ - (1720017472.013793, [], [1, 2, 3, 4, 5, 6]), - (1720238395.438066, [], [1, 2, 3, 4, 5, 6]), - (1720481118.520931, [], [1, 2, 3, 4, 5, 6]), - (1720624077.141735, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720460985.277631, [], [1, 2, 3, 4, 5, 6])], - [(1720065960.10824, [], [1, 2, 3, 4, 5, 6]), (1720568092.250721, [], [1, 2, 3, 4, 5, 6])], - [(1719964803.220143, [], [1, 2, 3, 4, 5, 6]), (1720072690.78503, [], [1, 2, 3, 4, 5, 6])], - [(1719973118.028284, [], [1, 2, 3, 4, 5, 6])], - [(1720148963.270876, [], [1, 2, 3, 4, 5, 6])], - [ - (1720055800.056897, [], [1, 2, 3, 4, 5, 6]), - (1720147428.656208, [], [1, 2, 3, 4, 5, 6]), - (1720237025.123131, [], [1, 2, 3, 4, 5, 6]), - (1720326902.440989, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719967443.988967, [], [1, 2, 3, 4, 5, 6]), - (1719967507.96168, [], [1, 2, 3, 4, 5, 6]), - (1719967510.01003, [], [1, 2, 3, 4, 5, 6]), - (1719967510.547419, [], [1, 2, 3, 4, 5, 6]), - (1719967512.630086, [], [1, 2, 3, 4, 5, 6]), - (1720138300.130825, [], [1, 2, 3, 4, 5, 6]), - (1720138300.228601, [], [1, 2, 3, 4, 5, 6]), - (1720138302.137449, [], [1, 2, 3, 4, 5, 6]), - (1720266243.760636, [], [1, 2, 3, 4, 5, 6]), - (1720266262.29505, [], [1, 2, 3, 4, 5, 6]), - (1720266262.382243, [], [1, 2, 3, 4, 5, 6]), - (1720266267.714044, [], [1, 2, 3, 4, 5, 6]), - (1720376066.44502, [], [1, 2, 3, 4, 5, 6]), - (1720376075.005446, [], [1, 2, 3, 4, 5, 6]), - (1720376075.055395, [], [1, 2, 3, 4, 5, 6]), - (1720376078.271297, [], [1, 2, 3, 4, 5, 6]), - (1720495615.317205, [], [1, 2, 3, 4, 5, 6]), - (1720495625.121167, [], [1, 2, 3, 4, 5, 6]), - (1720495627.190587, [], [1, 2, 3, 4, 5, 6]), - (1720495631.668389, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720094115.933922, [], [1, 2, 3, 4, 5, 6])], - [(1720327035.126978, [], [1, 2, 3, 4, 5, 6]), (1720652576.382878, [], [1, 2, 3, 4, 5, 6])], - [(1720494001.577927, [], [1, 2, 3, 4, 5, 6])], - [ - (1720102356.301353, [], [1, 2, 3, 4, 5, 6]), - (1720244955.2084, [], [1, 2, 3, 4, 5, 6]), - (1720393949.41044, [], [1, 2, 3, 4, 5, 6]), - (1720576986.579566, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720033048.609785, [], [1, 2, 3, 4, 5, 6])], - [(1720402968.773862, [], [1, 2, 3, 4, 5, 6])], - [(1720230211.716966, [], [1, 2, 3, 4, 5, 6])], - [ - (1720059787.289306, [], [1, 2, 3, 4, 5, 6]), - (1720397378.208597, [], [1, 2, 3, 4, 5, 6]), - (1720481196.422422, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720003149.057462, [], [1, 2, 3, 4, 5, 6]), - (1720003372.883061, [], [1, 2, 3, 4, 5, 6]), - (1720003374.955179, [], [1, 2, 3, 4, 5, 6]), - (1720039541.861276, [], [1, 2, 3, 4, 5, 6]), - (1720039688.427965, [], [1, 2, 3, 4, 5, 6]), - (1720039690.485555, [], [1, 2, 3, 4, 5, 6]), - (1720048625.116329, [], [1, 2, 3, 4, 5, 6]), - (1720048725.117697, [], [1, 2, 3, 4, 5, 6]), - (1720141659.610639, [], [1, 2, 3, 4, 5, 6]), - (1720141661.665952, [], [1, 2, 3, 4, 5, 6]), - (1720196426.042225, [], [1, 2, 3, 4, 5, 6]), - (1720196487.09087, [], [1, 2, 3, 4, 5, 6]), - (1720196489.183893, [], [1, 2, 3, 4, 5, 6]), - (1720207066.952798, [], [1, 2, 3, 4, 5, 6]), - (1720207237.857105, [], [1, 2, 3, 4, 5, 6]), - (1720207239.919375, [], [1, 2, 3, 4, 5, 6]), - (1720271033.503072, [], [1, 2, 3, 4, 5, 6]), - (1720271035.587795, [], [1, 2, 3, 4, 5, 6]), - (1720583123.471438, [], [1, 2, 3, 4, 5, 6]), - (1720583125.576798, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720154856.626343, [], [1, 2, 3, 4, 5, 6]), - (1720226072.346309, [], [1, 2, 3, 4, 5, 6]), - (1720310601.449016, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720242303.35601, [], [1, 2, 3, 4, 5, 6])], - [(1720078404.748142, [], [1, 2, 3, 4, 5, 6]), (1720147584.809447, [], [1, 2, 3, 4, 5, 6])], - [(1720178488.289574, [], [1, 2, 3, 4, 5, 6]), (1720306985.894457, [], [1, 2, 3, 4, 5, 6])], - [(1720146748.830901, [], [1, 2, 3, 4, 5, 6]), (1720406666.368212, [], [1, 2, 3, 4, 5, 6])], - [ - (1720023013.684634, [], [1, 2, 3, 4, 5, 6]), - (1720091577.184398, [], [1, 2, 3, 4, 5, 6]), - (1720415121.299085, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720056649.932043, [], [1, 2, 3, 4, 5, 6])], - [ - (1720323285.584787, [], [1, 2, 3, 4, 5, 6]), - (1720415154.592994, [], [1, 2, 3, 4, 5, 6]), - (1720437978.9498, [], [1, 2, 3, 4, 5, 6]), - (1720473849.744602, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719984649.0919, [], [1, 2, 3, 4, 5, 6]), - (1719984690.14033, [], [1, 2, 3, 4, 5, 6]), - (1720049900.611104, [], [1, 2, 3, 4, 5, 6]), - (1720049902.719326, [], [1, 2, 3, 4, 5, 6]), - (1720070202.827545, [], [1, 2, 3, 4, 5, 6]), - (1720070219.8164, [], [1, 2, 3, 4, 5, 6]), - (1720070221.892056, [], [1, 2, 3, 4, 5, 6]), - (1720137406.074377, [], [1, 2, 3, 4, 5, 6]), - (1720137495.69452, [], [1, 2, 3, 4, 5, 6]), - (1720137497.797134, [], [1, 2, 3, 4, 5, 6]), - (1720328661.139393, [], [1, 2, 3, 4, 5, 6]), - (1720328739.939669, [], [1, 2, 3, 4, 5, 6]), - (1720498901.295947, [], [1, 2, 3, 4, 5, 6]), - (1720570987.624349, [], [1, 2, 3, 4, 5, 6]), - (1720602646.235039, [], [1, 2, 3, 4, 5, 6]), - (1720602812.376711, [], [1, 2, 3, 4, 5, 6]), - (1720602814.446349, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974528.289353, [], [1, 2, 3, 4, 5, 6]), - (1720395723.591687, [], [1, 2, 3, 4, 5, 6]), - (1720617442.004095, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719975592.337919, [], [1, 2, 3, 4, 5, 6])], - [(1720057591.780745, [], [1, 2, 3, 4, 5, 6]), (1720488152.255523, [], [1, 2, 3, 4, 5, 6])], - [ - (1720148926.955422, [], [1, 2, 3, 4, 5, 6]), - (1720232410.538746, [], [1, 2, 3, 4, 5, 6]), - (1720408447.752538, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720242892.942203, [], [1, 2, 3, 4, 5, 6]), (1720322823.10199, [], [1, 2, 3, 4, 5, 6])], - [(1720400088.852099, [], [1, 2, 3, 4, 5, 6]), (1720652752.741385, [], [1, 2, 3, 4, 5, 6])], - [(1720412428.936544, [], [1, 2, 3, 4, 5, 6]), (1720574790.414977, [], [1, 2, 3, 4, 5, 6])], - [(1720069130.346249, [], [1, 2, 3, 4, 5, 6])], - [ - (1720157382.402748, [], [1, 2, 3, 4, 5, 6]), - (1720157476.064866, [], [1, 2, 3, 4, 5, 6]), - (1720157570.728611, [], [1, 2, 3, 4, 5, 6]), - (1720157662.381552, [], [1, 2, 3, 4, 5, 6]), - (1720168580.805279, [], [1, 2, 3, 4, 5, 6]), - (1720168760.793692, [], [1, 2, 3, 4, 5, 6]), - (1720230288.646191, [], [1, 2, 3, 4, 5, 6]), - (1720230430.103977, [], [1, 2, 3, 4, 5, 6]), - (1720243393.667459, [], [1, 2, 3, 4, 5, 6]), - (1720311604.919662, [], [1, 2, 3, 4, 5, 6]), - (1720311771.258364, [], [1, 2, 3, 4, 5, 6]), - (1720311773.310317, [], [1, 2, 3, 4, 5, 6]), - (1720324823.664232, [], [1, 2, 3, 4, 5, 6]), - (1720324825.721978, [], [1, 2, 3, 4, 5, 6]), - (1720393374.344255, [], [1, 2, 3, 4, 5, 6]), - (1720410680.226051, [], [1, 2, 3, 4, 5, 6]), - (1720410682.252163, [], [1, 2, 3, 4, 5, 6]), - (1720498394.961086, [], [1, 2, 3, 4, 5, 6]), - (1720498440.73496, [], [1, 2, 3, 4, 5, 6]), - (1720569716.948564, [], [1, 2, 3, 4, 5, 6]), - (1720569812.275586, [], [1, 2, 3, 4, 5, 6]), - (1720569814.333894, [], [1, 2, 3, 4, 5, 6]), - (1720569814.53133, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719978988.407662, [], [1, 2, 3, 4, 5, 6]), - (1719978990.511958, [], [1, 2, 3, 4, 5, 6]), - (1719984066.593696, [], [1, 2, 3, 4, 5, 6]), - (1719984323.803693, [], [1, 2, 3, 4, 5, 6]), - (1719984325.863773, [], [1, 2, 3, 4, 5, 6]), - (1720152078.595081, [], [1, 2, 3, 4, 5, 6]), - (1720225565.930941, [], [1, 2, 3, 4, 5, 6]), - (1720280378.036955, [], [1, 2, 3, 4, 5, 6]), - (1720326955.218979, [], [1, 2, 3, 4, 5, 6]), - (1720326957.292481, [], [1, 2, 3, 4, 5, 6]), - (1720331017.031137, [], [1, 2, 3, 4, 5, 6]), - (1720331019.121504, [], [1, 2, 3, 4, 5, 6]), - (1720410756.685202, [], [1, 2, 3, 4, 5, 6]), - (1720410758.796614, [], [1, 2, 3, 4, 5, 6]), - (1720417802.859919, [], [1, 2, 3, 4, 5, 6]), - (1720417804.989442, [], [1, 2, 3, 4, 5, 6]), - (1720487313.059882, [], [1, 2, 3, 4, 5, 6]), - (1720487498.533155, [], [1, 2, 3, 4, 5, 6]), - (1720487500.652063, [], [1, 2, 3, 4, 5, 6]), - (1720487503.708405, [], [1, 2, 3, 4, 5, 6]), - (1720487505.805861, [], [1, 2, 3, 4, 5, 6]), - (1720501546.266299, [], [1, 2, 3, 4, 5, 6]), - (1720501655.51812, [], [1, 2, 3, 4, 5, 6]), - (1720575741.153236, [], [1, 2, 3, 4, 5, 6]), - (1720575891.79104, [], [1, 2, 3, 4, 5, 6]), - (1720589520.786652, [], [1, 2, 3, 4, 5, 6]), - (1720589642.390304, [], [1, 2, 3, 4, 5, 6]), - (1720589644.452771, [], [1, 2, 3, 4, 5, 6]), - (1720615233.591986, [], [1, 2, 3, 4, 5, 6]), - (1720615337.890481, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719971542.018584, [], [1, 2, 3, 4, 5, 6]), - (1719971788.12398, [], [1, 2, 3, 4, 5, 6]), - (1720117268.913487, [], [1, 2, 3, 4, 5, 6]), - (1720117270.991206, [], [1, 2, 3, 4, 5, 6]), - (1720143198.612101, [], [1, 2, 3, 4, 5, 6]), - (1720143429.084839, [], [1, 2, 3, 4, 5, 6]), - (1720238625.308642, [], [1, 2, 3, 4, 5, 6]), - (1720238757.81922, [], [1, 2, 3, 4, 5, 6]), - (1720238759.894117, [], [1, 2, 3, 4, 5, 6]), - (1720330550.917977, [], [1, 2, 3, 4, 5, 6]), - (1720330626.459228, [], [1, 2, 3, 4, 5, 6]), - (1720378937.313156, [], [1, 2, 3, 4, 5, 6]), - (1720379038.375789, [], [1, 2, 3, 4, 5, 6]), - (1720386358.224787, [], [1, 2, 3, 4, 5, 6]), - (1720386360.275601, [], [1, 2, 3, 4, 5, 6]), - (1720416486.117358, [], [1, 2, 3, 4, 5, 6]), - (1720416608.109114, [], [1, 2, 3, 4, 5, 6]), - (1720493716.833205, [], [1, 2, 3, 4, 5, 6]), - (1720493844.641363, [], [1, 2, 3, 4, 5, 6]), - (1720493846.67691, [], [1, 2, 3, 4, 5, 6]), - (1720568118.486107, [], [1, 2, 3, 4, 5, 6]), - (1720568219.230995, [], [1, 2, 3, 4, 5, 6]), - (1720568221.334344, [], [1, 2, 3, 4, 5, 6]), - (1720574746.351324, [], [1, 2, 3, 4, 5, 6]), - (1720574815.297689, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720233195.120615, [], [1, 2, 3, 4, 5, 6]), - (1720393731.964556, [], [1, 2, 3, 4, 5, 6]), - (1720570257.699261, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720149655.238203, [], [1, 2, 3, 4, 5, 6]), - (1720352361.227124, [], [1, 2, 3, 4, 5, 6]), - (1720578697.147852, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720411277.985506, [], [1, 2, 3, 4, 5, 6]), (1720572981.673421, [], [1, 2, 3, 4, 5, 6])], - [(1720569584.93865, [], [1, 2, 3, 4, 5, 6])], - [(1720311303.894177, [], [1, 2, 3, 4, 5, 6])], - [(1720576463.87807, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982989.782732, [], [1, 2, 3, 4, 5, 6]), - (1720080708.007665, [], [1, 2, 3, 4, 5, 6]), - (1720234553.333259, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719983711.203136, [], [1, 2, 3, 4, 5, 6]), (1720395076.590109, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968905.802345, [], [1, 2, 3, 4, 5, 6]), - (1720054751.228152, [], [1, 2, 3, 4, 5, 6]), - (1720393228.571573, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720151965.57438, [], [1, 2, 3, 4, 5, 6]), - (1720265917.280767, [], [1, 2, 3, 4, 5, 6]), - (1720414597.498797, [], [1, 2, 3, 4, 5, 6]), - (1720569352.211054, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720139623.448558, [], [1, 2, 3, 4, 5, 6]), (1720413909.371495, [], [1, 2, 3, 4, 5, 6])], - [ - (1720332156.972433, [], [1, 2, 3, 4, 5, 6]), - (1720486770.808084, [], [1, 2, 3, 4, 5, 6]), - (1720570506.129092, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720046377.309817, [], [1, 2, 3, 4, 5, 6]), (1720144405.103977, [], [1, 2, 3, 4, 5, 6])], - [(1720311749.460887, [], [1, 2, 3, 4, 5, 6]), (1720480404.801297, [], [1, 2, 3, 4, 5, 6])], - [(1719965504.779832, [], [1, 2, 3, 4, 5, 6])], - [(1720489219.425884, [], [1, 2, 3, 4, 5, 6])], - [(1720480774.306063, [], [1, 2, 3, 4, 5, 6])], - [(1719968486.759348, [], [1, 2, 3, 4, 5, 6]), (1720229505.650825, [], [1, 2, 3, 4, 5, 6])], - [(1720122526.844622, [], [1, 2, 3, 4, 5, 6]), (1720142320.524851, [], [1, 2, 3, 4, 5, 6])], - [(1720320995.267452, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984296.990609, [], [1, 2, 3, 4, 5, 6]), - (1719984350.22369, [], [1, 2, 3, 4, 5, 6]), - (1719984352.257572, [], [1, 2, 3, 4, 5, 6]), - (1720052997.807277, [], [1, 2, 3, 4, 5, 6]), - (1720053049.304507, [], [1, 2, 3, 4, 5, 6]), - (1720053051.378602, [], [1, 2, 3, 4, 5, 6]), - (1720150389.546489, [], [1, 2, 3, 4, 5, 6]), - (1720150391.660121, [], [1, 2, 3, 4, 5, 6]), - (1720168392.833864, [], [1, 2, 3, 4, 5, 6]), - (1720168394.931787, [], [1, 2, 3, 4, 5, 6]), - (1720218901.13549, [], [1, 2, 3, 4, 5, 6]), - (1720218984.364651, [], [1, 2, 3, 4, 5, 6]), - (1720218986.444335, [], [1, 2, 3, 4, 5, 6]), - (1720236871.413173, [], [1, 2, 3, 4, 5, 6]), - (1720236873.52, [], [1, 2, 3, 4, 5, 6]), - (1720318899.245869, [], [1, 2, 3, 4, 5, 6]), - (1720319077.080816, [], [1, 2, 3, 4, 5, 6]), - (1720319079.181328, [], [1, 2, 3, 4, 5, 6]), - (1720421585.966107, [], [1, 2, 3, 4, 5, 6]), - (1720421692.177002, [], [1, 2, 3, 4, 5, 6]), - (1720421694.269891, [], [1, 2, 3, 4, 5, 6]), - (1720484559.101295, [], [1, 2, 3, 4, 5, 6]), - (1720484634.686657, [], [1, 2, 3, 4, 5, 6]), - (1720484636.791229, [], [1, 2, 3, 4, 5, 6]), - (1720484640.876498, [], [1, 2, 3, 4, 5, 6]), - (1720484642.914839, [], [1, 2, 3, 4, 5, 6]), - (1720568978.955929, [], [1, 2, 3, 4, 5, 6]), - (1720569083.551067, [], [1, 2, 3, 4, 5, 6]), - (1720603472.634189, [], [1, 2, 3, 4, 5, 6]), - (1720603622.57534, [], [1, 2, 3, 4, 5, 6]), - (1720603624.69381, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720204831.715905, [], [1, 2, 3, 4, 5, 6])], - [(1719985836.773241, [], [1, 2, 3, 4, 5, 6]), (1720227063.151216, [], [1, 2, 3, 4, 5, 6])], - [(1720226998.434162, [], [1, 2, 3, 4, 5, 6])], - [(1720413326.470543, [], [1, 2, 3, 4, 5, 6])], - [(1720484747.542658, [], [1, 2, 3, 4, 5, 6])], - [ - (1719975290.47648, [], [1, 2, 3, 4, 5, 6]), - (1719975421.539502, [], [1, 2, 3, 4, 5, 6]), - (1719975423.609947, [], [1, 2, 3, 4, 5, 6]), - (1719975424.130571, [], [1, 2, 3, 4, 5, 6]), - (1719975426.224942, [], [1, 2, 3, 4, 5, 6]), - (1720024823.782769, [], [1, 2, 3, 4, 5, 6]), - (1720024943.32157, [], [1, 2, 3, 4, 5, 6]), - (1720024945.350078, [], [1, 2, 3, 4, 5, 6]), - (1720024945.905366, [], [1, 2, 3, 4, 5, 6]), - (1720056619.663053, [], [1, 2, 3, 4, 5, 6]), - (1720056822.318399, [], [1, 2, 3, 4, 5, 6]), - (1720056824.36183, [], [1, 2, 3, 4, 5, 6]), - (1720072281.168332, [], [1, 2, 3, 4, 5, 6]), - (1720072283.222603, [], [1, 2, 3, 4, 5, 6]), - (1720134154.949613, [], [1, 2, 3, 4, 5, 6]), - (1720134376.323715, [], [1, 2, 3, 4, 5, 6]), - (1720134378.416906, [], [1, 2, 3, 4, 5, 6]), - (1720140112.874786, [], [1, 2, 3, 4, 5, 6]), - (1720140131.322854, [], [1, 2, 3, 4, 5, 6]), - (1720140133.38169, [], [1, 2, 3, 4, 5, 6]), - (1720238635.597737, [], [1, 2, 3, 4, 5, 6]), - (1720238637.672121, [], [1, 2, 3, 4, 5, 6]), - (1720418306.625113, [], [1, 2, 3, 4, 5, 6]), - (1720418333.5673, [], [1, 2, 3, 4, 5, 6]), - (1720487528.439985, [], [1, 2, 3, 4, 5, 6]), - (1720487546.337876, [], [1, 2, 3, 4, 5, 6]), - (1720487548.449392, [], [1, 2, 3, 4, 5, 6]), - (1720502509.125496, [], [1, 2, 3, 4, 5, 6]), - (1720502624.411704, [], [1, 2, 3, 4, 5, 6]), - (1720585053.028856, [], [1, 2, 3, 4, 5, 6]), - (1720585055.08891, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719982052.592392, [], [1, 2, 3, 4, 5, 6]), - (1719982258.203523, [], [1, 2, 3, 4, 5, 6]), - (1719985183.079021, [], [1, 2, 3, 4, 5, 6]), - (1719985305.780432, [], [1, 2, 3, 4, 5, 6]), - (1720055777.47168, [], [1, 2, 3, 4, 5, 6]), - (1720071284.174477, [], [1, 2, 3, 4, 5, 6]), - (1720152558.44266, [], [1, 2, 3, 4, 5, 6]), - (1720152671.333552, [], [1, 2, 3, 4, 5, 6]), - (1720152673.415669, [], [1, 2, 3, 4, 5, 6]), - (1720182134.94743, [], [1, 2, 3, 4, 5, 6]), - (1720182137.028427, [], [1, 2, 3, 4, 5, 6]), - (1720182138.842693, [], [1, 2, 3, 4, 5, 6]), - (1720182140.958073, [], [1, 2, 3, 4, 5, 6]), - (1720227575.333539, [], [1, 2, 3, 4, 5, 6]), - (1720227736.260264, [], [1, 2, 3, 4, 5, 6]), - (1720227738.300477, [], [1, 2, 3, 4, 5, 6]), - (1720236068.538351, [], [1, 2, 3, 4, 5, 6]), - (1720236070.60483, [], [1, 2, 3, 4, 5, 6]), - (1720317757.071545, [], [1, 2, 3, 4, 5, 6]), - (1720317866.130343, [], [1, 2, 3, 4, 5, 6]), - (1720317868.22788, [], [1, 2, 3, 4, 5, 6]), - (1720330462.980036, [], [1, 2, 3, 4, 5, 6]), - (1720330707.655663, [], [1, 2, 3, 4, 5, 6]), - (1720330709.750072, [], [1, 2, 3, 4, 5, 6]), - (1720373940.747523, [], [1, 2, 3, 4, 5, 6]), - (1720374027.697475, [], [1, 2, 3, 4, 5, 6]), - (1720374029.799405, [], [1, 2, 3, 4, 5, 6]), - (1720406670.90306, [], [1, 2, 3, 4, 5, 6]), - (1720406844.478936, [], [1, 2, 3, 4, 5, 6]), - (1720406846.592556, [], [1, 2, 3, 4, 5, 6]), - (1720406851.281701, [], [1, 2, 3, 4, 5, 6]), - (1720412576.66958, [], [1, 2, 3, 4, 5, 6]), - (1720412652.412012, [], [1, 2, 3, 4, 5, 6]), - (1720412654.533239, [], [1, 2, 3, 4, 5, 6]), - (1720486184.910769, [], [1, 2, 3, 4, 5, 6]), - (1720571066.49819, [], [1, 2, 3, 4, 5, 6]), - (1720626129.788949, [], [1, 2, 3, 4, 5, 6]), - (1720626261.332132, [], [1, 2, 3, 4, 5, 6]), - (1720626263.446226, [], [1, 2, 3, 4, 5, 6]), - (1720626267.27108, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719972691.157799, [], [1, 2, 3, 4, 5, 6]), - (1719972822.458675, [], [1, 2, 3, 4, 5, 6]), - (1719972824.589752, [], [1, 2, 3, 4, 5, 6]), - (1719993329.829737, [], [1, 2, 3, 4, 5, 6]), - (1720053155.834123, [], [1, 2, 3, 4, 5, 6]), - (1720053293.330528, [], [1, 2, 3, 4, 5, 6]), - (1720084358.281667, [], [1, 2, 3, 4, 5, 6]), - (1720084522.554824, [], [1, 2, 3, 4, 5, 6]), - (1720084524.658959, [], [1, 2, 3, 4, 5, 6]), - (1720153146.842639, [], [1, 2, 3, 4, 5, 6]), - (1720153159.620793, [], [1, 2, 3, 4, 5, 6]), - (1720223041.359927, [], [1, 2, 3, 4, 5, 6]), - (1720223107.178767, [], [1, 2, 3, 4, 5, 6]), - (1720223109.301943, [], [1, 2, 3, 4, 5, 6]), - (1720243608.145196, [], [1, 2, 3, 4, 5, 6]), - (1720243715.813915, [], [1, 2, 3, 4, 5, 6]), - (1720310055.295457, [], [1, 2, 3, 4, 5, 6]), - (1720310225.190394, [], [1, 2, 3, 4, 5, 6]), - (1720310227.250668, [], [1, 2, 3, 4, 5, 6]), - (1720374255.295948, [], [1, 2, 3, 4, 5, 6]), - (1720374257.390432, [], [1, 2, 3, 4, 5, 6]), - (1720397033.790744, [], [1, 2, 3, 4, 5, 6]), - (1720397192.93351, [], [1, 2, 3, 4, 5, 6]), - (1720489562.012912, [], [1, 2, 3, 4, 5, 6]), - (1720489620.124167, [], [1, 2, 3, 4, 5, 6]), - (1720489622.2461, [], [1, 2, 3, 4, 5, 6]), - (1720577615.944083, [], [1, 2, 3, 4, 5, 6]), - (1720595908.263871, [], [1, 2, 3, 4, 5, 6]), - (1720596022.795818, [], [1, 2, 3, 4, 5, 6]), - (1720596024.909409, [], [1, 2, 3, 4, 5, 6]), - (1720596025.112291, [], [1, 2, 3, 4, 5, 6]), - (1720596027.181848, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720410184.878056, [], [1, 2, 3, 4, 5, 6])], - [(1720446097.457008, [], [1, 2, 3, 4, 5, 6]), (1720582142.651169, [], [1, 2, 3, 4, 5, 6])], - [(1720496385.651227, [], [1, 2, 3, 4, 5, 6]), (1720588018.159792, [], [1, 2, 3, 4, 5, 6])], - [(1719975737.968693, [], [1, 2, 3, 4, 5, 6]), (1720069758.403541, [], [1, 2, 3, 4, 5, 6])], - [(1720573220.196789, [], [1, 2, 3, 4, 5, 6])], - [(1720435170.4772, [], [1, 2, 3, 4, 5, 6])], - [(1720156838.062846, [], [1, 2, 3, 4, 5, 6]), (1720588244.606338, [], [1, 2, 3, 4, 5, 6])], - [(1720072706.921977, [], [1, 2, 3, 4, 5, 6]), (1720588899.722119, [], [1, 2, 3, 4, 5, 6])], - [(1720058343.607628, [], [1, 2, 3, 4, 5, 6])], - [(1720314365.315505, [], [1, 2, 3, 4, 5, 6])], - [(1720502417.751936, [], [1, 2, 3, 4, 5, 6])], - [(1720302708.367359, [], [1, 2, 3, 4, 5, 6]), (1720585704.559633, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984540.656777, [], [1, 2, 3, 4, 5, 6]), - (1720146973.8651, [], [1, 2, 3, 4, 5, 6]), - (1720341798.159409, [], [1, 2, 3, 4, 5, 6]), - (1720482149.273983, [], [1, 2, 3, 4, 5, 6]), - (1720570969.604085, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720311167.154928, [], [1, 2, 3, 4, 5, 6]), (1720404884.472902, [], [1, 2, 3, 4, 5, 6])], - [(1720481370.176729, [], [1, 2, 3, 4, 5, 6])], - [(1720098969.778426, [], [1, 2, 3, 4, 5, 6]), (1720542708.023885, [], [1, 2, 3, 4, 5, 6])], - [ - (1720149583.597081, [], [1, 2, 3, 4, 5, 6]), - (1720314574.406545, [], [1, 2, 3, 4, 5, 6]), - (1720416038.659142, [], [1, 2, 3, 4, 5, 6]), - (1720572347.697131, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720033450.660601, [], [1, 2, 3, 4, 5, 6]), - (1720033450.752555, [], [1, 2, 3, 4, 5, 6]), - (1720033455.770905, [], [1, 2, 3, 4, 5, 6]), - (1720400227.89913, [], [1, 2, 3, 4, 5, 6]), - (1720400250.299243, [], [1, 2, 3, 4, 5, 6]), - (1720400252.394995, [], [1, 2, 3, 4, 5, 6]), - (1720417432.186774, [], [1, 2, 3, 4, 5, 6]), - (1720417504.33498, [], [1, 2, 3, 4, 5, 6]), - (1720417506.39095, [], [1, 2, 3, 4, 5, 6]), - (1720417509.515927, [], [1, 2, 3, 4, 5, 6]), - (1720417511.647347, [], [1, 2, 3, 4, 5, 6]), - (1720417512.311827, [], [1, 2, 3, 4, 5, 6]), - (1720512787.544525, [], [1, 2, 3, 4, 5, 6]), - (1720512787.637452, [], [1, 2, 3, 4, 5, 6]), - (1720512790.509437, [], [1, 2, 3, 4, 5, 6]), - (1720546384.085434, [], [1, 2, 3, 4, 5, 6]), - (1720546402.635026, [], [1, 2, 3, 4, 5, 6]), - (1720546404.721606, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720091612.414745, [], [1, 2, 3, 4, 5, 6]), (1720394180.692823, [], [1, 2, 3, 4, 5, 6])], - [(1720499565.692616, [], [1, 2, 3, 4, 5, 6])], - [ - (1720050050.500015, [], [1, 2, 3, 4, 5, 6]), - (1720050118.092842, [], [1, 2, 3, 4, 5, 6]), - (1720050225.108458, [], [1, 2, 3, 4, 5, 6]), - (1720065727.65261, [], [1, 2, 3, 4, 5, 6]), - (1720065830.735126, [], [1, 2, 3, 4, 5, 6]), - (1720065888.617825, [], [1, 2, 3, 4, 5, 6]), - (1720065986.346168, [], [1, 2, 3, 4, 5, 6]), - (1720066099.675624, [], [1, 2, 3, 4, 5, 6]), - (1720066274.481661, [], [1, 2, 3, 4, 5, 6]), - (1720066349.195281, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720151340.048882, [], [1, 2, 3, 4, 5, 6]), - (1720314849.375028, [], [1, 2, 3, 4, 5, 6]), - (1720413869.9313, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720054419.118301, [], [1, 2, 3, 4, 5, 6]), (1720399142.008777, [], [1, 2, 3, 4, 5, 6])], - [ - (1720070403.925696, [], [1, 2, 3, 4, 5, 6]), - (1720244978.0606, [], [1, 2, 3, 4, 5, 6]), - (1720588083.280232, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720142944.669634, [], [1, 2, 3, 4, 5, 6]), - (1720317829.682224, [], [1, 2, 3, 4, 5, 6]), - (1720402172.873968, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720135813.27587, [], [1, 2, 3, 4, 5, 6]), - (1720344219.879026, [], [1, 2, 3, 4, 5, 6]), - (1720587780.127476, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720307062.497702, [], [1, 2, 3, 4, 5, 6])], - [(1720145491.250495, [], [1, 2, 3, 4, 5, 6]), (1720586242.178403, [], [1, 2, 3, 4, 5, 6])], - [(1720586566.015615, [], [1, 2, 3, 4, 5, 6])], - [(1720409077.369118, [], [1, 2, 3, 4, 5, 6]), (1720569722.833936, [], [1, 2, 3, 4, 5, 6])], - [(1720098442.029928, [], [1, 2, 3, 4, 5, 6]), (1720391796.053942, [], [1, 2, 3, 4, 5, 6])], - [(1720243240.863801, [], [1, 2, 3, 4, 5, 6]), (1720492060.909226, [], [1, 2, 3, 4, 5, 6])], - [ - (1719967064.859664, [], [1, 2, 3, 4, 5, 6]), - (1720055971.205432, [], [1, 2, 3, 4, 5, 6]), - (1720056017.075129, [], [1, 2, 3, 4, 5, 6]), - (1720069354.406111, [], [1, 2, 3, 4, 5, 6]), - (1720069356.466395, [], [1, 2, 3, 4, 5, 6]), - (1720153990.829373, [], [1, 2, 3, 4, 5, 6]), - (1720154034.130574, [], [1, 2, 3, 4, 5, 6]), - (1720232518.365492, [], [1, 2, 3, 4, 5, 6]), - (1720232668.084829, [], [1, 2, 3, 4, 5, 6]), - (1720232670.147567, [], [1, 2, 3, 4, 5, 6]), - (1720247796.598987, [], [1, 2, 3, 4, 5, 6]), - (1720310742.132713, [], [1, 2, 3, 4, 5, 6]), - (1720310784.012123, [], [1, 2, 3, 4, 5, 6]), - (1720320091.334971, [], [1, 2, 3, 4, 5, 6]), - (1720357505.367765, [], [1, 2, 3, 4, 5, 6]), - (1720357507.406388, [], [1, 2, 3, 4, 5, 6]), - (1720404625.988586, [], [1, 2, 3, 4, 5, 6]), - (1720404726.50447, [], [1, 2, 3, 4, 5, 6]), - (1720404728.609789, [], [1, 2, 3, 4, 5, 6]), - (1720417440.696768, [], [1, 2, 3, 4, 5, 6]), - (1720460381.831877, [], [1, 2, 3, 4, 5, 6]), - (1720460489.831088, [], [1, 2, 3, 4, 5, 6]), - (1720492881.459734, [], [1, 2, 3, 4, 5, 6]), - (1720492883.570789, [], [1, 2, 3, 4, 5, 6]), - (1720580680.591028, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719975556.382414, [], [1, 2, 3, 4, 5, 6]), (1720231475.932226, [], [1, 2, 3, 4, 5, 6])], - [(1720569569.754826, [], [1, 2, 3, 4, 5, 6])], - [(1720043952.413223, [], [1, 2, 3, 4, 5, 6]), (1720225500.222696, [], [1, 2, 3, 4, 5, 6])], - [ - (1719967819.052883, [], [1, 2, 3, 4, 5, 6]), - (1720234292.697748, [], [1, 2, 3, 4, 5, 6]), - (1720397113.348799, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720087477.672876, [], [1, 2, 3, 4, 5, 6]), (1720438489.760021, [], [1, 2, 3, 4, 5, 6])], - [(1720577383.739689, [], [1, 2, 3, 4, 5, 6])], - [ - (1720047896.111507, [], [1, 2, 3, 4, 5, 6]), - (1720200244.93862, [], [1, 2, 3, 4, 5, 6]), - (1720464543.942733, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719970307.394382, [], [1, 2, 3, 4, 5, 6])], - [(1719982131.954439, [], [1, 2, 3, 4, 5, 6]), (1720238111.874625, [], [1, 2, 3, 4, 5, 6])], - [(1719966189.201726, [], [1, 2, 3, 4, 5, 6]), (1720150700.452652, [], [1, 2, 3, 4, 5, 6])], - [(1720142072.057736, [], [1, 2, 3, 4, 5, 6])], - [(1720063956.632264, [], [1, 2, 3, 4, 5, 6])], - [(1720057020.243682, [], [1, 2, 3, 4, 5, 6])], - [ - (1719973656.343743, [], [1, 2, 3, 4, 5, 6]), - (1719973767.615562, [], [1, 2, 3, 4, 5, 6]), - (1719973769.702368, [], [1, 2, 3, 4, 5, 6]), - (1720050422.073716, [], [1, 2, 3, 4, 5, 6]), - (1720060932.515015, [], [1, 2, 3, 4, 5, 6]), - (1720061076.268193, [], [1, 2, 3, 4, 5, 6]), - (1720061078.375626, [], [1, 2, 3, 4, 5, 6]), - (1720061082.695369, [], [1, 2, 3, 4, 5, 6]), - (1720061084.803345, [], [1, 2, 3, 4, 5, 6]), - (1720061088.695247, [], [1, 2, 3, 4, 5, 6]), - (1720061090.795592, [], [1, 2, 3, 4, 5, 6]), - (1720135057.814031, [], [1, 2, 3, 4, 5, 6]), - (1720135295.655111, [], [1, 2, 3, 4, 5, 6]), - (1720135297.734383, [], [1, 2, 3, 4, 5, 6]), - (1720156608.706907, [], [1, 2, 3, 4, 5, 6]), - (1720156610.771323, [], [1, 2, 3, 4, 5, 6]), - (1720208160.885537, [], [1, 2, 3, 4, 5, 6]), - (1720208274.821579, [], [1, 2, 3, 4, 5, 6]), - (1720208276.929569, [], [1, 2, 3, 4, 5, 6]), - (1720223270.224257, [], [1, 2, 3, 4, 5, 6]), - (1720223272.316827, [], [1, 2, 3, 4, 5, 6]), - (1720223275.15326, [], [1, 2, 3, 4, 5, 6]), - (1720261350.082829, [], [1, 2, 3, 4, 5, 6]), - (1720261423.329391, [], [1, 2, 3, 4, 5, 6]), - (1720261425.427693, [], [1, 2, 3, 4, 5, 6]), - (1720319448.712298, [], [1, 2, 3, 4, 5, 6]), - (1720319512.283877, [], [1, 2, 3, 4, 5, 6]), - (1720319514.384024, [], [1, 2, 3, 4, 5, 6]), - (1720397163.860459, [], [1, 2, 3, 4, 5, 6]), - (1720397201.824506, [], [1, 2, 3, 4, 5, 6]), - (1720397203.898302, [], [1, 2, 3, 4, 5, 6]), - (1720487465.098454, [], [1, 2, 3, 4, 5, 6]), - (1720487616.241062, [], [1, 2, 3, 4, 5, 6]), - (1720576783.799559, [], [1, 2, 3, 4, 5, 6]), - (1720576837.625767, [], [1, 2, 3, 4, 5, 6]), - (1720576839.747181, [], [1, 2, 3, 4, 5, 6]), - (1720621584.709553, [], [1, 2, 3, 4, 5, 6]), - (1720621686.14789, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720210871.32264, [], [1, 2, 3, 4, 5, 6]), (1720324564.785043, [], [1, 2, 3, 4, 5, 6])], - [ - (1719976074.774068, [], [1, 2, 3, 4, 5, 6]), - (1720432422.057214, [], [1, 2, 3, 4, 5, 6]), - (1720498059.505822, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720537307.322626, [], [1, 2, 3, 4, 5, 6])], - [(1720051279.943281, [], [1, 2, 3, 4, 5, 6]), (1720326635.291429, [], [1, 2, 3, 4, 5, 6])], - [ - (1720317156.788498, [], [1, 2, 3, 4, 5, 6]), - (1720409687.362687, [], [1, 2, 3, 4, 5, 6]), - (1720499324.086042, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720058380.956986, [], [1, 2, 3, 4, 5, 6]), (1720150021.258812, [], [1, 2, 3, 4, 5, 6])], - [ - (1720053489.906165, [], [1, 2, 3, 4, 5, 6]), - (1720139673.741326, [], [1, 2, 3, 4, 5, 6]), - (1720257769.454421, [], [1, 2, 3, 4, 5, 6]), - (1720393246.483443, [], [1, 2, 3, 4, 5, 6]), - (1720653126.121555, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719980029.84453, [], [1, 2, 3, 4, 5, 6])], - [(1720579706.660021, [], [1, 2, 3, 4, 5, 6])], - [(1720044200.360238, [], [1, 2, 3, 4, 5, 6])], - [(1720081853.12837, [], [1, 2, 3, 4, 5, 6])], - [(1720052881.805602, [], [1, 2, 3, 4, 5, 6])], - [ - (1720072654.6007, [], [1, 2, 3, 4, 5, 6]), - (1720238922.414211, [], [1, 2, 3, 4, 5, 6]), - (1720410048.118631, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720307869.769519, [], [1, 2, 3, 4, 5, 6])], - [ - (1720016591.216479, [], [1, 2, 3, 4, 5, 6]), - (1720157097.134758, [], [1, 2, 3, 4, 5, 6]), - (1720238731.063819, [], [1, 2, 3, 4, 5, 6]), - (1720575486.387284, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965711.424761, [], [1, 2, 3, 4, 5, 6]), - (1719965713.531779, [], [1, 2, 3, 4, 5, 6]), - (1720049361.440421, [], [1, 2, 3, 4, 5, 6]), - (1720049363.495467, [], [1, 2, 3, 4, 5, 6]), - (1720070584.34326, [], [1, 2, 3, 4, 5, 6]), - (1720070586.439897, [], [1, 2, 3, 4, 5, 6]), - (1720070588.168108, [], [1, 2, 3, 4, 5, 6]), - (1720154076.359366, [], [1, 2, 3, 4, 5, 6]), - (1720154271.555582, [], [1, 2, 3, 4, 5, 6]), - (1720221139.621509, [], [1, 2, 3, 4, 5, 6]), - (1720221264.378154, [], [1, 2, 3, 4, 5, 6]), - (1720221266.479342, [], [1, 2, 3, 4, 5, 6]), - (1720239415.452192, [], [1, 2, 3, 4, 5, 6]), - (1720239475.014596, [], [1, 2, 3, 4, 5, 6]), - (1720239477.07742, [], [1, 2, 3, 4, 5, 6]), - (1720313035.217622, [], [1, 2, 3, 4, 5, 6]), - (1720313041.373706, [], [1, 2, 3, 4, 5, 6]), - (1720313043.420222, [], [1, 2, 3, 4, 5, 6]), - (1720406631.8599, [], [1, 2, 3, 4, 5, 6]), - (1720406659.023715, [], [1, 2, 3, 4, 5, 6]), - (1720484615.165994, [], [1, 2, 3, 4, 5, 6]), - (1720484638.913162, [], [1, 2, 3, 4, 5, 6]), - (1720497880.450011, [], [1, 2, 3, 4, 5, 6]), - (1720497934.842426, [], [1, 2, 3, 4, 5, 6]), - (1720497936.912581, [], [1, 2, 3, 4, 5, 6]), - (1720540604.563371, [], [1, 2, 3, 4, 5, 6]), - (1720540779.42356, [], [1, 2, 3, 4, 5, 6]), - (1720540781.553641, [], [1, 2, 3, 4, 5, 6]), - (1720570083.468668, [], [1, 2, 3, 4, 5, 6]), - (1720570174.103962, [], [1, 2, 3, 4, 5, 6]), - (1720570176.16906, [], [1, 2, 3, 4, 5, 6]), - (1720583667.401678, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719984388.470208, [], [1, 2, 3, 4, 5, 6]), - (1720057777.644161, [], [1, 2, 3, 4, 5, 6]), - (1720057953.012529, [], [1, 2, 3, 4, 5, 6]), - (1720057955.119335, [], [1, 2, 3, 4, 5, 6]), - (1720148795.685708, [], [1, 2, 3, 4, 5, 6]), - (1720148805.802813, [], [1, 2, 3, 4, 5, 6]), - (1720148807.834184, [], [1, 2, 3, 4, 5, 6]), - (1720234649.035149, [], [1, 2, 3, 4, 5, 6]), - (1720234705.911474, [], [1, 2, 3, 4, 5, 6]), - (1720321956.32096, [], [1, 2, 3, 4, 5, 6]), - (1720321958.41442, [], [1, 2, 3, 4, 5, 6]), - (1720409662.220157, [], [1, 2, 3, 4, 5, 6]), - (1720409664.333692, [], [1, 2, 3, 4, 5, 6]), - (1720447795.315077, [], [1, 2, 3, 4, 5, 6]), - (1720447797.391813, [], [1, 2, 3, 4, 5, 6]), - (1720483016.135213, [], [1, 2, 3, 4, 5, 6]), - (1720483018.21033, [], [1, 2, 3, 4, 5, 6]), - (1720483019.948558, [], [1, 2, 3, 4, 5, 6]), - (1720573042.040836, [], [1, 2, 3, 4, 5, 6]), - (1720573166.473551, [], [1, 2, 3, 4, 5, 6]), - (1720624631.359534, [], [1, 2, 3, 4, 5, 6]), - (1720624673.478312, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720072684.014623, [], [1, 2, 3, 4, 5, 6]), - (1720308176.896274, [], [1, 2, 3, 4, 5, 6]), - (1720404626.250723, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719970599.437881, [], [1, 2, 3, 4, 5, 6]), - (1720066959.831691, [], [1, 2, 3, 4, 5, 6]), - (1720067155.392921, [], [1, 2, 3, 4, 5, 6]), - (1720067157.488109, [], [1, 2, 3, 4, 5, 6]), - (1720155932.952678, [], [1, 2, 3, 4, 5, 6]), - (1720156052.447154, [], [1, 2, 3, 4, 5, 6]), - (1720156054.565087, [], [1, 2, 3, 4, 5, 6]), - (1720176991.157569, [], [1, 2, 3, 4, 5, 6]), - (1720177007.156433, [], [1, 2, 3, 4, 5, 6]), - (1720197632.204363, [], [1, 2, 3, 4, 5, 6]), - (1720197634.246364, [], [1, 2, 3, 4, 5, 6]), - (1720245139.96838, [], [1, 2, 3, 4, 5, 6]), - (1720245142.060531, [], [1, 2, 3, 4, 5, 6]), - (1720313085.938317, [], [1, 2, 3, 4, 5, 6]), - (1720313087.991269, [], [1, 2, 3, 4, 5, 6]), - (1720382887.239454, [], [1, 2, 3, 4, 5, 6]), - (1720383102.784337, [], [1, 2, 3, 4, 5, 6]), - (1720383104.858248, [], [1, 2, 3, 4, 5, 6]), - (1720401645.882852, [], [1, 2, 3, 4, 5, 6]), - (1720401875.751914, [], [1, 2, 3, 4, 5, 6]), - (1720401877.871081, [], [1, 2, 3, 4, 5, 6]), - (1720401879.349072, [], [1, 2, 3, 4, 5, 6]), - (1720401881.439362, [], [1, 2, 3, 4, 5, 6]), - (1720414595.608826, [], [1, 2, 3, 4, 5, 6]), - (1720414633.289105, [], [1, 2, 3, 4, 5, 6]), - (1720414635.359202, [], [1, 2, 3, 4, 5, 6]), - (1720417003.580682, [], [1, 2, 3, 4, 5, 6]), - (1720417074.130853, [], [1, 2, 3, 4, 5, 6]), - (1720417076.197409, [], [1, 2, 3, 4, 5, 6]), - (1720480715.553431, [], [1, 2, 3, 4, 5, 6]), - (1720480828.705337, [], [1, 2, 3, 4, 5, 6]), - (1720480830.783164, [], [1, 2, 3, 4, 5, 6]), - (1720579482.271054, [], [1, 2, 3, 4, 5, 6]), - (1720579503.249382, [], [1, 2, 3, 4, 5, 6]), - (1720579505.309044, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720320578.9281, [], [1, 2, 3, 4, 5, 6]), - (1720320637.501704, [], [1, 2, 3, 4, 5, 6]), - (1720320671.3461, [], [1, 2, 3, 4, 5, 6]), - (1720320700.900689, [], [1, 2, 3, 4, 5, 6]), - (1720326925.640353, [], [1, 2, 3, 4, 5, 6]), - (1720326927.740401, [], [1, 2, 3, 4, 5, 6]), - (1720397880.433215, [], [1, 2, 3, 4, 5, 6]), - (1720397991.949085, [], [1, 2, 3, 4, 5, 6]), - (1720407395.883774, [], [1, 2, 3, 4, 5, 6]), - (1720478571.564518, [], [1, 2, 3, 4, 5, 6]), - (1720478573.689929, [], [1, 2, 3, 4, 5, 6]), - (1720496055.710657, [], [1, 2, 3, 4, 5, 6]), - (1720496250.423433, [], [1, 2, 3, 4, 5, 6]), - (1720496252.533919, [], [1, 2, 3, 4, 5, 6]), - (1720567595.861171, [], [1, 2, 3, 4, 5, 6]), - (1720567634.8402, [], [1, 2, 3, 4, 5, 6]), - (1720567636.90682, [], [1, 2, 3, 4, 5, 6]), - (1720652785.237133, [], [1, 2, 3, 4, 5, 6]), - (1720652836.758383, [], [1, 2, 3, 4, 5, 6]), - (1720652838.851539, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720076323.446198, [], [1, 2, 3, 4, 5, 6]), - (1720076387.202961, [], [1, 2, 3, 4, 5, 6]), - (1720076463.503404, [], [1, 2, 3, 4, 5, 6]), - (1720235511.111341, [], [1, 2, 3, 4, 5, 6]), - (1720235587.152102, [], [1, 2, 3, 4, 5, 6]), - (1720235604.104726, [], [1, 2, 3, 4, 5, 6]), - (1720235788.441489, [], [1, 2, 3, 4, 5, 6]), - (1720235897.829327, [], [1, 2, 3, 4, 5, 6]), - (1720235943.361057, [], [1, 2, 3, 4, 5, 6]), - (1720236088.122922, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719969865.146509, [], [1, 2, 3, 4, 5, 6])], - [ - (1720088372.900286, [], [1, 2, 3, 4, 5, 6]), - (1720220494.799398, [], [1, 2, 3, 4, 5, 6]), - (1720488909.409034, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720063420.61895, [], [1, 2, 3, 4, 5, 6]), - (1720320803.577679, [], [1, 2, 3, 4, 5, 6]), - (1720401999.385093, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720051291.94966, [], [1, 2, 3, 4, 5, 6]), (1720313692.587964, [], [1, 2, 3, 4, 5, 6])], - [(1720509709.170957, [], [1, 2, 3, 4, 5, 6]), (1720652928.475583, [], [1, 2, 3, 4, 5, 6])], - [(1719976500.586248, [], [1, 2, 3, 4, 5, 6])], - [(1720063184.061031, [], [1, 2, 3, 4, 5, 6])], - [(1720147998.634564, [], [1, 2, 3, 4, 5, 6]), (1720575037.093899, [], [1, 2, 3, 4, 5, 6])], - [(1720594897.858543, [], [1, 2, 3, 4, 5, 6])], - [ - (1720238660.290085, [], [1, 2, 3, 4, 5, 6]), - (1720306835.46462, [], [1, 2, 3, 4, 5, 6]), - (1720401110.356341, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719970976.422012, [], [1, 2, 3, 4, 5, 6]), - (1720051629.137902, [], [1, 2, 3, 4, 5, 6]), - (1720301759.327348, [], [1, 2, 3, 4, 5, 6]), - (1720646663.705407, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720077214.628033, [], [1, 2, 3, 4, 5, 6]), (1720579842.451312, [], [1, 2, 3, 4, 5, 6])], - [(1720403179.578891, [], [1, 2, 3, 4, 5, 6]), (1720573175.772465, [], [1, 2, 3, 4, 5, 6])], - [ - (1720418161.36421, [], [1, 2, 3, 4, 5, 6]), - (1720418260.71249, [], [1, 2, 3, 4, 5, 6]), - (1720418315.726571, [], [1, 2, 3, 4, 5, 6]), - (1720418380.031953, [], [1, 2, 3, 4, 5, 6]), - (1720491482.634884, [], [1, 2, 3, 4, 5, 6]), - (1720491528.332034, [], [1, 2, 3, 4, 5, 6]), - (1720491530.434212, [], [1, 2, 3, 4, 5, 6]), - (1720573999.084897, [], [1, 2, 3, 4, 5, 6]), - (1720574047.543743, [], [1, 2, 3, 4, 5, 6]), - (1720574049.630747, [], [1, 2, 3, 4, 5, 6]), - (1720616534.181229, [], [1, 2, 3, 4, 5, 6]), - (1720616536.227681, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719971505.975792, [], [1, 2, 3, 4, 5, 6]), - (1720309386.016213, [], [1, 2, 3, 4, 5, 6]), - (1720570539.167487, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720026981.201845, [], [1, 2, 3, 4, 5, 6]), - (1720063393.228975, [], [1, 2, 3, 4, 5, 6]), - (1720569870.489752, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720151334.562097, [], [1, 2, 3, 4, 5, 6]), - (1720311454.894847, [], [1, 2, 3, 4, 5, 6]), - (1720483363.072169, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720051176.858561, [], [1, 2, 3, 4, 5, 6]), (1720567049.0934, [], [1, 2, 3, 4, 5, 6])], - [ - (1720300278.98565, [], [1, 2, 3, 4, 5, 6]), - (1720397622.151994, [], [1, 2, 3, 4, 5, 6]), - (1720487075.583534, [], [1, 2, 3, 4, 5, 6]), - (1720572927.092976, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720588311.663694, [], [1, 2, 3, 4, 5, 6])], - [(1720323338.447054, [], [1, 2, 3, 4, 5, 6])], - [(1720499740.21156, [], [1, 2, 3, 4, 5, 6])], - [(1720239215.924016, [], [1, 2, 3, 4, 5, 6]), (1720407168.197067, [], [1, 2, 3, 4, 5, 6])], - [(1720496803.3956, [], [1, 2, 3, 4, 5, 6])], - [(1720578053.220463, [], [1, 2, 3, 4, 5, 6])], - [(1720400566.962842, [], [1, 2, 3, 4, 5, 6]), (1720652817.676145, [], [1, 2, 3, 4, 5, 6])], - [ - (1720234566.739671, [], [1, 2, 3, 4, 5, 6]), - (1720335553.524142, [], [1, 2, 3, 4, 5, 6]), - (1720576366.993741, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720058095.694475, [], [1, 2, 3, 4, 5, 6])], - [(1720499846.305083, [], [1, 2, 3, 4, 5, 6])], - [(1720069736.856188, [], [1, 2, 3, 4, 5, 6]), (1720327054.018462, [], [1, 2, 3, 4, 5, 6])], - [(1720446989.50202, [], [1, 2, 3, 4, 5, 6]), (1720579246.321269, [], [1, 2, 3, 4, 5, 6])], - [ - (1720065515.046196, [], [1, 2, 3, 4, 5, 6]), - (1720237193.252454, [], [1, 2, 3, 4, 5, 6]), - (1720402549.014306, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965737.195869, [], [1, 2, 3, 4, 5, 6]), - (1720057334.427369, [], [1, 2, 3, 4, 5, 6]), - (1720221205.840325, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720366343.985963, [], [1, 2, 3, 4, 5, 6])], - [(1720195598.557753, [], [1, 2, 3, 4, 5, 6])], - [(1719980678.939359, [], [1, 2, 3, 4, 5, 6]), (1720144995.169791, [], [1, 2, 3, 4, 5, 6])], - [(1720583721.214132, [], [1, 2, 3, 4, 5, 6])], - [ - (1720054537.756175, [], [1, 2, 3, 4, 5, 6]), - (1720182546.976397, [], [1, 2, 3, 4, 5, 6]), - (1720415420.418491, [], [1, 2, 3, 4, 5, 6]), - (1720491014.558376, [], [1, 2, 3, 4, 5, 6]), - (1720568712.840731, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720061881.320656, [], [1, 2, 3, 4, 5, 6]), - (1720352102.705661, [], [1, 2, 3, 4, 5, 6]), - (1720405007.368123, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720578542.112522, [], [1, 2, 3, 4, 5, 6]), (1720652582.644175, [], [1, 2, 3, 4, 5, 6])], - [(1720243826.422296, [], [1, 2, 3, 4, 5, 6])], - [ - (1719980177.888359, [], [1, 2, 3, 4, 5, 6]), - (1720151191.015847, [], [1, 2, 3, 4, 5, 6]), - (1720578744.147878, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720401711.559261, [], [1, 2, 3, 4, 5, 6])], - [ - (1720166076.219132, [], [1, 2, 3, 4, 5, 6]), - (1720603429.438791, [], [1, 2, 3, 4, 5, 6]), - (1720653029.910009, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060428.267185, [], [1, 2, 3, 4, 5, 6]), (1720330543.204866, [], [1, 2, 3, 4, 5, 6])], - [(1720023596.681592, [], [1, 2, 3, 4, 5, 6]), (1720492712.578171, [], [1, 2, 3, 4, 5, 6])], - [ - (1719969468.250895, [], [1, 2, 3, 4, 5, 6]), - (1719969673.12603, [], [1, 2, 3, 4, 5, 6]), - (1719984075.563213, [], [1, 2, 3, 4, 5, 6]), - (1719984158.542506, [], [1, 2, 3, 4, 5, 6]), - (1719984160.639094, [], [1, 2, 3, 4, 5, 6]), - (1719984161.840978, [], [1, 2, 3, 4, 5, 6]), - (1720063496.706949, [], [1, 2, 3, 4, 5, 6]), - (1720063498.73801, [], [1, 2, 3, 4, 5, 6]), - (1720071811.706281, [], [1, 2, 3, 4, 5, 6]), - (1720071892.339384, [], [1, 2, 3, 4, 5, 6]), - (1720071894.401443, [], [1, 2, 3, 4, 5, 6]), - (1720141092.670014, [], [1, 2, 3, 4, 5, 6]), - (1720141281.129314, [], [1, 2, 3, 4, 5, 6]), - (1720141283.221705, [], [1, 2, 3, 4, 5, 6]), - (1720242813.561025, [], [1, 2, 3, 4, 5, 6]), - (1720242887.120065, [], [1, 2, 3, 4, 5, 6]), - (1720242889.197122, [], [1, 2, 3, 4, 5, 6]), - (1720314744.527265, [], [1, 2, 3, 4, 5, 6]), - (1720314759.642908, [], [1, 2, 3, 4, 5, 6]), - (1720314761.711826, [], [1, 2, 3, 4, 5, 6]), - (1720371097.307425, [], [1, 2, 3, 4, 5, 6]), - (1720371255.548011, [], [1, 2, 3, 4, 5, 6]), - (1720387058.372995, [], [1, 2, 3, 4, 5, 6]), - (1720387060.502073, [], [1, 2, 3, 4, 5, 6]), - (1720404975.528018, [], [1, 2, 3, 4, 5, 6]), - (1720405017.654969, [], [1, 2, 3, 4, 5, 6]), - (1720405019.759385, [], [1, 2, 3, 4, 5, 6]), - (1720415081.995346, [], [1, 2, 3, 4, 5, 6]), - (1720415260.662438, [], [1, 2, 3, 4, 5, 6]), - (1720415262.742795, [], [1, 2, 3, 4, 5, 6]), - (1720485117.023333, [], [1, 2, 3, 4, 5, 6]), - (1720485119.095263, [], [1, 2, 3, 4, 5, 6]), - (1720499098.798714, [], [1, 2, 3, 4, 5, 6]), - (1720499235.930954, [], [1, 2, 3, 4, 5, 6]), - (1720499238.042676, [], [1, 2, 3, 4, 5, 6]), - (1720569739.038396, [], [1, 2, 3, 4, 5, 6]), - (1720569853.204944, [], [1, 2, 3, 4, 5, 6]), - (1720569855.2363, [], [1, 2, 3, 4, 5, 6]), - (1720602936.713875, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720242969.422529, [], [1, 2, 3, 4, 5, 6])], - [ - (1719964838.834772, [], [1, 2, 3, 4, 5, 6]), - (1720091821.44426, [], [1, 2, 3, 4, 5, 6]), - (1720233192.310563, [], [1, 2, 3, 4, 5, 6]), - (1720328141.79034, [], [1, 2, 3, 4, 5, 6]), - (1720496224.014897, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720152285.903631, [], [1, 2, 3, 4, 5, 6]), - (1720243334.372125, [], [1, 2, 3, 4, 5, 6]), - (1720379463.678962, [], [1, 2, 3, 4, 5, 6]), - (1720542353.379097, [], [1, 2, 3, 4, 5, 6]), - (1720649368.688756, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720226523.433881, [], [1, 2, 3, 4, 5, 6]), - (1720226623.918185, [], [1, 2, 3, 4, 5, 6]), - (1720226651.194519, [], [1, 2, 3, 4, 5, 6]), - (1720226742.683406, [], [1, 2, 3, 4, 5, 6]), - (1720330187.550014, [], [1, 2, 3, 4, 5, 6]), - (1720330210.231169, [], [1, 2, 3, 4, 5, 6]), - (1720410272.539479, [], [1, 2, 3, 4, 5, 6]), - (1720410274.655647, [], [1, 2, 3, 4, 5, 6]), - (1720480303.2625, [], [1, 2, 3, 4, 5, 6]), - (1720480415.671856, [], [1, 2, 3, 4, 5, 6]), - (1720480417.738288, [], [1, 2, 3, 4, 5, 6]), - (1720504693.498524, [], [1, 2, 3, 4, 5, 6]), - (1720504764.21831, [], [1, 2, 3, 4, 5, 6]), - (1720504766.268173, [], [1, 2, 3, 4, 5, 6]), - (1720568377.567722, [], [1, 2, 3, 4, 5, 6]), - (1720568452.706691, [], [1, 2, 3, 4, 5, 6]), - (1720568454.778127, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720150751.139246, [], [1, 2, 3, 4, 5, 6])], - [ - (1720064945.077586, [], [1, 2, 3, 4, 5, 6]), - (1720176851.77124, [], [1, 2, 3, 4, 5, 6]), - (1720413751.53369, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720067667.982332, [], [1, 2, 3, 4, 5, 6]), - (1720498323.491767, [], [1, 2, 3, 4, 5, 6]), - (1720640332.912224, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720586416.962046, [], [1, 2, 3, 4, 5, 6])], - [(1720403065.106609, [], [1, 2, 3, 4, 5, 6]), (1720468529.097883, [], [1, 2, 3, 4, 5, 6])], - [(1719976409.626599, [], [1, 2, 3, 4, 5, 6]), (1720617974.74258, [], [1, 2, 3, 4, 5, 6])], - [(1720155789.338418, [], [1, 2, 3, 4, 5, 6])], - [(1719965523.519862, [], [1, 2, 3, 4, 5, 6])], - [(1720492317.02938, [], [1, 2, 3, 4, 5, 6])], - [ - (1719971602.527103, [], [1, 2, 3, 4, 5, 6]), - (1720069918.036547, [], [1, 2, 3, 4, 5, 6]), - (1720149900.77775, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720143447.493022, [], [1, 2, 3, 4, 5, 6]), (1720292005.708479, [], [1, 2, 3, 4, 5, 6])], - [(1720316731.010367, [], [1, 2, 3, 4, 5, 6])], - [(1720061643.180585, [], [1, 2, 3, 4, 5, 6])], - [ - (1719998587.453659, [], [1, 2, 3, 4, 5, 6]), - (1720141642.077196, [], [1, 2, 3, 4, 5, 6]), - (1720308402.56405, [], [1, 2, 3, 4, 5, 6]), - (1720416584.28358, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720587211.681421, [], [1, 2, 3, 4, 5, 6])], - [(1720155992.271335, [], [1, 2, 3, 4, 5, 6]), (1720572458.818891, [], [1, 2, 3, 4, 5, 6])], - [(1720052898.053761, [], [1, 2, 3, 4, 5, 6])], - [(1720221610.587492, [], [1, 2, 3, 4, 5, 6]), (1720312064.403238, [], [1, 2, 3, 4, 5, 6])], - [ - (1720147178.948005, [], [1, 2, 3, 4, 5, 6]), - (1720315892.264762, [], [1, 2, 3, 4, 5, 6]), - (1720484335.142158, [], [1, 2, 3, 4, 5, 6]), - (1720625426.867126, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720225964.225383, [], [1, 2, 3, 4, 5, 6]), (1720486617.901554, [], [1, 2, 3, 4, 5, 6])], - [(1720064206.744859, [], [1, 2, 3, 4, 5, 6]), (1720148855.512919, [], [1, 2, 3, 4, 5, 6])], - [ - (1719978022.859036, [], [1, 2, 3, 4, 5, 6]), - (1720225065.814898, [], [1, 2, 3, 4, 5, 6]), - (1720379679.901663, [], [1, 2, 3, 4, 5, 6]), - (1720486481.106043, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720072107.565425, [], [1, 2, 3, 4, 5, 6]), (1720244247.598994, [], [1, 2, 3, 4, 5, 6])], - [(1720418305.8177, [], [1, 2, 3, 4, 5, 6])], - [(1719982059.871483, [], [1, 2, 3, 4, 5, 6])], - [(1719978817.113542, [], [1, 2, 3, 4, 5, 6])], - [(1720138229.977179, [], [1, 2, 3, 4, 5, 6])], - [(1720069967.627991, [], [1, 2, 3, 4, 5, 6]), (1720327850.533176, [], [1, 2, 3, 4, 5, 6])], - [(1720047008.96098, [], [1, 2, 3, 4, 5, 6]), (1720399885.70332, [], [1, 2, 3, 4, 5, 6])], - [(1720241326.183043, [], [1, 2, 3, 4, 5, 6])], - [ - (1719974240.573502, [], [1, 2, 3, 4, 5, 6]), - (1719974319.570753, [], [1, 2, 3, 4, 5, 6]), - (1719974321.645618, [], [1, 2, 3, 4, 5, 6]), - (1720023281.111928, [], [1, 2, 3, 4, 5, 6]), - (1720023484.341612, [], [1, 2, 3, 4, 5, 6]), - (1720023486.442918, [], [1, 2, 3, 4, 5, 6]), - (1720056803.840688, [], [1, 2, 3, 4, 5, 6]), - (1720056805.906524, [], [1, 2, 3, 4, 5, 6]), - (1720056810.106719, [], [1, 2, 3, 4, 5, 6]), - (1720056812.20004, [], [1, 2, 3, 4, 5, 6]), - (1720070833.346034, [], [1, 2, 3, 4, 5, 6]), - (1720070835.405627, [], [1, 2, 3, 4, 5, 6]), - (1720070839.751918, [], [1, 2, 3, 4, 5, 6]), - (1720070841.8631, [], [1, 2, 3, 4, 5, 6]), - (1720143274.991396, [], [1, 2, 3, 4, 5, 6]), - (1720143497.358536, [], [1, 2, 3, 4, 5, 6]), - (1720205396.067954, [], [1, 2, 3, 4, 5, 6]), - (1720205567.621928, [], [1, 2, 3, 4, 5, 6]), - (1720235968.291387, [], [1, 2, 3, 4, 5, 6]), - (1720236089.012578, [], [1, 2, 3, 4, 5, 6]), - (1720236091.096483, [], [1, 2, 3, 4, 5, 6]), - (1720299309.484376, [], [1, 2, 3, 4, 5, 6]), - (1720299348.029909, [], [1, 2, 3, 4, 5, 6]), - (1720299350.111093, [], [1, 2, 3, 4, 5, 6]), - (1720320587.866423, [], [1, 2, 3, 4, 5, 6]), - (1720320589.944508, [], [1, 2, 3, 4, 5, 6]), - (1720400218.389368, [], [1, 2, 3, 4, 5, 6]), - (1720400220.487059, [], [1, 2, 3, 4, 5, 6]), - (1720492976.763916, [], [1, 2, 3, 4, 5, 6]), - (1720493019.503907, [], [1, 2, 3, 4, 5, 6]), - (1720493021.579652, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720122662.758187, [], [1, 2, 3, 4, 5, 6])], - [ - (1720005466.226878, [], [1, 2, 3, 4, 5, 6]), - (1720152200.991189, [], [1, 2, 3, 4, 5, 6]), - (1720481835.844194, [], [1, 2, 3, 4, 5, 6]), - (1720580183.828864, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720070662.89957, [], [1, 2, 3, 4, 5, 6])], - [(1720142183.650314, [], [1, 2, 3, 4, 5, 6]), (1720411252.551579, [], [1, 2, 3, 4, 5, 6])], - [(1720072507.675137, [], [1, 2, 3, 4, 5, 6]), (1720238913.204492, [], [1, 2, 3, 4, 5, 6])], - [(1720218011.114445, [], [1, 2, 3, 4, 5, 6])], - [(1720302385.101079, [], [1, 2, 3, 4, 5, 6])], - [(1720570186.762002, [], [1, 2, 3, 4, 5, 6])], - [(1720157661.668233, [], [1, 2, 3, 4, 5, 6])], - [ - (1720002096.475822, [], [1, 2, 3, 4, 5, 6]), - (1720002098.548489, [], [1, 2, 3, 4, 5, 6]), - (1720066947.715378, [], [1, 2, 3, 4, 5, 6]), - (1720066949.844651, [], [1, 2, 3, 4, 5, 6]), - (1720105199.7729, [], [1, 2, 3, 4, 5, 6]), - (1720105370.978068, [], [1, 2, 3, 4, 5, 6]), - (1720105373.072451, [], [1, 2, 3, 4, 5, 6]), - (1720134686.761223, [], [1, 2, 3, 4, 5, 6]), - (1720134688.87969, [], [1, 2, 3, 4, 5, 6]), - (1720154938.58341, [], [1, 2, 3, 4, 5, 6]), - (1720219977.007902, [], [1, 2, 3, 4, 5, 6]), - (1720219979.064108, [], [1, 2, 3, 4, 5, 6]), - (1720250673.20197, [], [1, 2, 3, 4, 5, 6]), - (1720250796.014257, [], [1, 2, 3, 4, 5, 6]), - (1720313894.440119, [], [1, 2, 3, 4, 5, 6]), - (1720313896.495204, [], [1, 2, 3, 4, 5, 6]), - (1720313896.774105, [], [1, 2, 3, 4, 5, 6]), - (1720396853.1643, [], [1, 2, 3, 4, 5, 6]), - (1720396855.257174, [], [1, 2, 3, 4, 5, 6]), - (1720489852.456446, [], [1, 2, 3, 4, 5, 6]), - (1720489986.86769, [], [1, 2, 3, 4, 5, 6]), - (1720569682.852233, [], [1, 2, 3, 4, 5, 6]), - (1720569767.225411, [], [1, 2, 3, 4, 5, 6]), - (1720569769.334261, [], [1, 2, 3, 4, 5, 6]), - (1720581192.763754, [], [1, 2, 3, 4, 5, 6]), - (1720581262.544992, [], [1, 2, 3, 4, 5, 6]), - (1720581264.629216, [], [1, 2, 3, 4, 5, 6]), - (1720581266.203535, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720226441.129883, [], [1, 2, 3, 4, 5, 6]), - (1720226519.948161, [], [1, 2, 3, 4, 5, 6]), - (1720226639.444269, [], [1, 2, 3, 4, 5, 6]), - (1720226731.198095, [], [1, 2, 3, 4, 5, 6]), - (1720226779.385516, [], [1, 2, 3, 4, 5, 6]), - (1720226788.674966, [], [1, 2, 3, 4, 5, 6]), - (1720226923.560385, [], [1, 2, 3, 4, 5, 6]), - (1720487951.436457, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720038002.665527, [], [1, 2, 3, 4, 5, 6]), - (1720488750.698306, [], [1, 2, 3, 4, 5, 6]), - (1720589885.270178, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720580260.501907, [], [1, 2, 3, 4, 5, 6])], - [(1720237662.32438, [], [1, 2, 3, 4, 5, 6]), (1720309542.106408, [], [1, 2, 3, 4, 5, 6])], - [(1720573441.412558, [], [1, 2, 3, 4, 5, 6])], - [(1720598006.382998, [], [1, 2, 3, 4, 5, 6])], - [(1720249262.676111, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968867.096755, [], [1, 2, 3, 4, 5, 6]), - (1720406515.635103, [], [1, 2, 3, 4, 5, 6]), - (1720568473.896114, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720063183.618875, [], [1, 2, 3, 4, 5, 6])], - [(1720313109.473272, [], [1, 2, 3, 4, 5, 6]), (1720418083.174351, [], [1, 2, 3, 4, 5, 6])], - [(1720106024.609, [], [1, 2, 3, 4, 5, 6])], - [(1720058454.321955, [], [1, 2, 3, 4, 5, 6])], - [ - (1720062639.625591, [], [1, 2, 3, 4, 5, 6]), - (1720221670.858026, [], [1, 2, 3, 4, 5, 6]), - (1720496857.495022, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974856.395033, [], [1, 2, 3, 4, 5, 6]), - (1720053608.017225, [], [1, 2, 3, 4, 5, 6]), - (1720053669.477447, [], [1, 2, 3, 4, 5, 6]), - (1720053671.560518, [], [1, 2, 3, 4, 5, 6]), - (1720062649.578553, [], [1, 2, 3, 4, 5, 6]), - (1720062651.66265, [], [1, 2, 3, 4, 5, 6]), - (1720062653.377042, [], [1, 2, 3, 4, 5, 6]), - (1720062655.44862, [], [1, 2, 3, 4, 5, 6]), - (1720082692.43711, [], [1, 2, 3, 4, 5, 6]), - (1720082771.847834, [], [1, 2, 3, 4, 5, 6]), - (1720153671.808662, [], [1, 2, 3, 4, 5, 6]), - (1720153713.489374, [], [1, 2, 3, 4, 5, 6]), - (1720153715.599402, [], [1, 2, 3, 4, 5, 6]), - (1720153716.387598, [], [1, 2, 3, 4, 5, 6]), - (1720153718.446591, [], [1, 2, 3, 4, 5, 6]), - (1720239246.152588, [], [1, 2, 3, 4, 5, 6]), - (1720239248.241024, [], [1, 2, 3, 4, 5, 6]), - (1720239250.77294, [], [1, 2, 3, 4, 5, 6]), - (1720309956.683905, [], [1, 2, 3, 4, 5, 6]), - (1720310071.602061, [], [1, 2, 3, 4, 5, 6]), - (1720325462.049867, [], [1, 2, 3, 4, 5, 6]), - (1720325503.88631, [], [1, 2, 3, 4, 5, 6]), - (1720325506.004479, [], [1, 2, 3, 4, 5, 6]), - (1720412942.492135, [], [1, 2, 3, 4, 5, 6]), - (1720458829.36376, [], [1, 2, 3, 4, 5, 6]), - (1720458949.800013, [], [1, 2, 3, 4, 5, 6]), - (1720458951.887504, [], [1, 2, 3, 4, 5, 6]), - (1720492407.820081, [], [1, 2, 3, 4, 5, 6]), - (1720492444.404348, [], [1, 2, 3, 4, 5, 6]), - (1720492446.466946, [], [1, 2, 3, 4, 5, 6]), - (1720575932.543872, [], [1, 2, 3, 4, 5, 6]), - (1720576033.410802, [], [1, 2, 3, 4, 5, 6]), - (1720576035.469127, [], [1, 2, 3, 4, 5, 6]), - (1720576036.44253, [], [1, 2, 3, 4, 5, 6]), - (1720647287.059052, [], [1, 2, 3, 4, 5, 6]), - (1720647289.160943, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720330899.088291, [], [1, 2, 3, 4, 5, 6])], - [ - (1720081793.462679, [], [1, 2, 3, 4, 5, 6]), - (1720081976.131384, [], [1, 2, 3, 4, 5, 6]), - (1720081976.187009, [], [1, 2, 3, 4, 5, 6]), - (1720081980.325716, [], [1, 2, 3, 4, 5, 6]), - (1720091170.691618, [], [1, 2, 3, 4, 5, 6]), - (1720091356.840132, [], [1, 2, 3, 4, 5, 6]), - (1720091358.928927, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720238399.047753, [], [1, 2, 3, 4, 5, 6]), (1720567368.683366, [], [1, 2, 3, 4, 5, 6])], - [(1720583646.429286, [], [1, 2, 3, 4, 5, 6])], - [(1720330049.16818, [], [1, 2, 3, 4, 5, 6])], - [(1720578076.222297, [], [1, 2, 3, 4, 5, 6])], - [(1719972331.112716, [], [1, 2, 3, 4, 5, 6]), (1720051745.533132, [], [1, 2, 3, 4, 5, 6])], - [(1720146463.601388, [], [1, 2, 3, 4, 5, 6]), (1720474541.840768, [], [1, 2, 3, 4, 5, 6])], - [ - (1720051898.891617, [], [1, 2, 3, 4, 5, 6]), - (1720173013.609275, [], [1, 2, 3, 4, 5, 6]), - (1720320493.657042, [], [1, 2, 3, 4, 5, 6]), - (1720345690.851927, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720408818.140609, [], [1, 2, 3, 4, 5, 6]), (1720486964.900766, [], [1, 2, 3, 4, 5, 6])], - [ - (1720043728.363322, [], [1, 2, 3, 4, 5, 6]), - (1720311975.271982, [], [1, 2, 3, 4, 5, 6]), - (1720571578.431424, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719972681.535491, [], [1, 2, 3, 4, 5, 6]), (1720481018.937328, [], [1, 2, 3, 4, 5, 6])], - [ - (1720026382.553301, [], [1, 2, 3, 4, 5, 6]), - (1720149100.706808, [], [1, 2, 3, 4, 5, 6]), - (1720307942.507634, [], [1, 2, 3, 4, 5, 6]), - (1720570495.6023, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720488173.923373, [], [1, 2, 3, 4, 5, 6]), (1720568447.027354, [], [1, 2, 3, 4, 5, 6])], - [(1720567270.126647, [], [1, 2, 3, 4, 5, 6])], - [(1720499324.726509, [], [1, 2, 3, 4, 5, 6])], - [(1719967975.358552, [], [1, 2, 3, 4, 5, 6]), (1720326137.056104, [], [1, 2, 3, 4, 5, 6])], - [(1720328587.433829, [], [1, 2, 3, 4, 5, 6])], - [ - (1720055336.001624, [], [1, 2, 3, 4, 5, 6]), - (1720138863.165013, [], [1, 2, 3, 4, 5, 6]), - (1720395924.519387, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720069032.516709, [], [1, 2, 3, 4, 5, 6])], - [(1720055010.518163, [], [1, 2, 3, 4, 5, 6]), (1720099339.150894, [], [1, 2, 3, 4, 5, 6])], - [(1720585549.317132, [], [1, 2, 3, 4, 5, 6])], - [ - (1720409221.504822, [], [1, 2, 3, 4, 5, 6]), - (1720519728.003909, [], [1, 2, 3, 4, 5, 6]), - (1720567616.396835, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720244626.143033, [], [1, 2, 3, 4, 5, 6]), - (1720408635.777109, [], [1, 2, 3, 4, 5, 6]), - (1720575490.310245, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720650559.825556, [], [1, 2, 3, 4, 5, 6])], - [(1720582328.399682, [], [1, 2, 3, 4, 5, 6])], - [(1720394085.218172, [], [1, 2, 3, 4, 5, 6])], - [ - (1720066065.444143, [], [1, 2, 3, 4, 5, 6]), - (1720191993.66672, [], [1, 2, 3, 4, 5, 6]), - (1720491329.586545, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720071639.073353, [], [1, 2, 3, 4, 5, 6]), - (1720147406.207381, [], [1, 2, 3, 4, 5, 6]), - (1720311129.234658, [], [1, 2, 3, 4, 5, 6]), - (1720573354.037576, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720240131.733437, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984704.452873, [], [1, 2, 3, 4, 5, 6]), - (1720154844.587696, [], [1, 2, 3, 4, 5, 6]), - (1720322613.231449, [], [1, 2, 3, 4, 5, 6]), - (1720569714.825725, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720486946.256934, [], [1, 2, 3, 4, 5, 6]), (1720647691.877446, [], [1, 2, 3, 4, 5, 6])], - [ - (1719993805.960143, [], [1, 2, 3, 4, 5, 6]), - (1720143738.25635, [], [1, 2, 3, 4, 5, 6]), - (1720309437.19401, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720398437.265534, [], [1, 2, 3, 4, 5, 6]), - (1720509793.976335, [], [1, 2, 3, 4, 5, 6]), - (1720629661.586274, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720062670.596985, [], [1, 2, 3, 4, 5, 6]), (1720438472.029491, [], [1, 2, 3, 4, 5, 6])], - [(1720329032.038648, [], [1, 2, 3, 4, 5, 6])], - [(1719984110.370743, [], [1, 2, 3, 4, 5, 6])], - [(1719986035.664892, [], [1, 2, 3, 4, 5, 6]), (1720241225.374801, [], [1, 2, 3, 4, 5, 6])], - [ - (1720105075.810739, [], [1, 2, 3, 4, 5, 6]), - (1720150414.362845, [], [1, 2, 3, 4, 5, 6]), - (1720308174.216706, [], [1, 2, 3, 4, 5, 6]), - (1720412581.759663, [], [1, 2, 3, 4, 5, 6]), - (1720567554.209717, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720537016.009206, [], [1, 2, 3, 4, 5, 6]), (1720589963.468469, [], [1, 2, 3, 4, 5, 6])], - [(1720487391.820061, [], [1, 2, 3, 4, 5, 6])], - [ - (1719975756.8334, [], [1, 2, 3, 4, 5, 6]), - (1720155078.652264, [], [1, 2, 3, 4, 5, 6]), - (1720400698.199527, [], [1, 2, 3, 4, 5, 6]), - (1720496832.791723, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720018681.490249, [], [1, 2, 3, 4, 5, 6]), - (1720136925.765051, [], [1, 2, 3, 4, 5, 6]), - (1720299976.82238, [], [1, 2, 3, 4, 5, 6]), - (1720569027.317754, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720154725.361924, [], [1, 2, 3, 4, 5, 6]), - (1720243905.535885, [], [1, 2, 3, 4, 5, 6]), - (1720315512.512864, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720588095.521256, [], [1, 2, 3, 4, 5, 6])], - [(1719983442.727069, [], [1, 2, 3, 4, 5, 6]), (1720152453.391462, [], [1, 2, 3, 4, 5, 6])], - [(1720405182.158931, [], [1, 2, 3, 4, 5, 6]), (1720575807.583852, [], [1, 2, 3, 4, 5, 6])], - [(1720069878.030512, [], [1, 2, 3, 4, 5, 6]), (1720168504.534482, [], [1, 2, 3, 4, 5, 6])], - [(1720239119.238416, [], [1, 2, 3, 4, 5, 6])], - [(1720576430.211377, [], [1, 2, 3, 4, 5, 6])], - [ - (1719972965.48613, [], [1, 2, 3, 4, 5, 6]), - (1720240976.867243, [], [1, 2, 3, 4, 5, 6]), - (1720404977.394327, [], [1, 2, 3, 4, 5, 6]), - (1720537004.359466, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720487019.528315, [], [1, 2, 3, 4, 5, 6]), (1720581959.239135, [], [1, 2, 3, 4, 5, 6])], - [(1720652926.990055, [], [1, 2, 3, 4, 5, 6])], - [ - (1720052099.960777, [], [1, 2, 3, 4, 5, 6]), - (1720138855.98453, [], [1, 2, 3, 4, 5, 6]), - (1720138921.586511, [], [1, 2, 3, 4, 5, 6]), - (1720139014.744606, [], [1, 2, 3, 4, 5, 6]), - (1720139182.595009, [], [1, 2, 3, 4, 5, 6]), - (1720139192.3206, [], [1, 2, 3, 4, 5, 6]), - (1720581909.908771, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720065955.899244, [], [1, 2, 3, 4, 5, 6]), - (1720236828.579322, [], [1, 2, 3, 4, 5, 6]), - (1720308640.597753, [], [1, 2, 3, 4, 5, 6]), - (1720579634.738256, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719980159.276761, [], [1, 2, 3, 4, 5, 6]), - (1720308552.424302, [], [1, 2, 3, 4, 5, 6]), - (1720653256.063729, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719985271.443965, [], [1, 2, 3, 4, 5, 6]), - (1720220543.115385, [], [1, 2, 3, 4, 5, 6]), - (1720315297.143816, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720330015.747888, [], [1, 2, 3, 4, 5, 6]), (1720481610.656596, [], [1, 2, 3, 4, 5, 6])], - [(1720224041.283015, [], [1, 2, 3, 4, 5, 6]), (1720567371.834809, [], [1, 2, 3, 4, 5, 6])], - [ - (1720244217.827624, [], [1, 2, 3, 4, 5, 6]), - (1720402557.505715, [], [1, 2, 3, 4, 5, 6]), - (1720502124.284452, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720415547.576014, [], [1, 2, 3, 4, 5, 6]), (1720531682.711315, [], [1, 2, 3, 4, 5, 6])], - [(1720407411.272993, [], [1, 2, 3, 4, 5, 6]), (1720574508.629738, [], [1, 2, 3, 4, 5, 6])], - [(1720257290.163002, [], [1, 2, 3, 4, 5, 6]), (1720492975.717018, [], [1, 2, 3, 4, 5, 6])], - [(1720144145.711511, [], [1, 2, 3, 4, 5, 6]), (1720401163.125022, [], [1, 2, 3, 4, 5, 6])], - [(1720355601.346282, [], [1, 2, 3, 4, 5, 6]), (1720572069.286814, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968339.260056, [], [1, 2, 3, 4, 5, 6]), - (1719968341.365428, [], [1, 2, 3, 4, 5, 6]), - (1719968343.993978, [], [1, 2, 3, 4, 5, 6]), - (1719968346.031381, [], [1, 2, 3, 4, 5, 6]), - (1719968349.431552, [], [1, 2, 3, 4, 5, 6]), - (1719968351.559689, [], [1, 2, 3, 4, 5, 6]), - (1719976134.941126, [], [1, 2, 3, 4, 5, 6]), - (1719976278.477066, [], [1, 2, 3, 4, 5, 6]), - (1719976280.56988, [], [1, 2, 3, 4, 5, 6]), - (1720052757.855887, [], [1, 2, 3, 4, 5, 6]), - (1720052759.915085, [], [1, 2, 3, 4, 5, 6]), - (1720110094.313929, [], [1, 2, 3, 4, 5, 6]), - (1720142517.707832, [], [1, 2, 3, 4, 5, 6]), - (1720142570.10559, [], [1, 2, 3, 4, 5, 6]), - (1720142572.151412, [], [1, 2, 3, 4, 5, 6]), - (1720142576.179553, [], [1, 2, 3, 4, 5, 6]), - (1720237055.807105, [], [1, 2, 3, 4, 5, 6]), - (1720237203.321556, [], [1, 2, 3, 4, 5, 6]), - (1720237205.419793, [], [1, 2, 3, 4, 5, 6]), - (1720316912.566247, [], [1, 2, 3, 4, 5, 6]), - (1720317055.804333, [], [1, 2, 3, 4, 5, 6]), - (1720317057.925258, [], [1, 2, 3, 4, 5, 6]), - (1720317058.399149, [], [1, 2, 3, 4, 5, 6]), - (1720317060.481448, [], [1, 2, 3, 4, 5, 6]), - (1720393849.766518, [], [1, 2, 3, 4, 5, 6]), - (1720393921.300236, [], [1, 2, 3, 4, 5, 6]), - (1720406796.853939, [], [1, 2, 3, 4, 5, 6]), - (1720406798.933918, [], [1, 2, 3, 4, 5, 6]), - (1720482599.505433, [], [1, 2, 3, 4, 5, 6]), - (1720482663.255581, [], [1, 2, 3, 4, 5, 6]), - (1720482665.27704, [], [1, 2, 3, 4, 5, 6]), - (1720492023.699542, [], [1, 2, 3, 4, 5, 6]), - (1720492025.737059, [], [1, 2, 3, 4, 5, 6]), - (1720500142.609638, [], [1, 2, 3, 4, 5, 6]), - (1720500250.895423, [], [1, 2, 3, 4, 5, 6]), - (1720525828.241699, [], [1, 2, 3, 4, 5, 6]), - (1720525830.335737, [], [1, 2, 3, 4, 5, 6]), - (1720543473.185403, [], [1, 2, 3, 4, 5, 6]), - (1720543629.193018, [], [1, 2, 3, 4, 5, 6]), - (1720543631.258205, [], [1, 2, 3, 4, 5, 6]), - (1720566115.315069, [], [1, 2, 3, 4, 5, 6]), - (1720566235.252146, [], [1, 2, 3, 4, 5, 6]), - (1720566237.371673, [], [1, 2, 3, 4, 5, 6]), - (1720566239.622085, [], [1, 2, 3, 4, 5, 6]), - (1720566241.74061, [], [1, 2, 3, 4, 5, 6]), - (1720652422.12376, [], [1, 2, 3, 4, 5, 6]), - (1720652589.161105, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720332940.235911, [], [1, 2, 3, 4, 5, 6])], - [(1720065527.859172, [], [1, 2, 3, 4, 5, 6])], - [(1720568368.543876, [], [1, 2, 3, 4, 5, 6]), (1720635472.219669, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968828.538353, [], [1, 2, 3, 4, 5, 6]), - (1720051948.377763, [], [1, 2, 3, 4, 5, 6]), - (1720299205.556357, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720235830.179481, [], [1, 2, 3, 4, 5, 6]), - (1720235953.147018, [], [1, 2, 3, 4, 5, 6]), - (1720236018.20472, [], [1, 2, 3, 4, 5, 6]), - (1720236089.138704, [], [1, 2, 3, 4, 5, 6]), - (1720236119.593712, [], [1, 2, 3, 4, 5, 6]), - (1720236141.83499, [], [1, 2, 3, 4, 5, 6]), - (1720311050.201652, [], [1, 2, 3, 4, 5, 6]), - (1720311052.280309, [], [1, 2, 3, 4, 5, 6]), - (1720395484.534496, [], [1, 2, 3, 4, 5, 6]), - (1720491406.080018, [], [1, 2, 3, 4, 5, 6]), - (1720491430.598198, [], [1, 2, 3, 4, 5, 6]), - (1720491432.661821, [], [1, 2, 3, 4, 5, 6]), - (1720572678.481313, [], [1, 2, 3, 4, 5, 6]), - (1720572808.45491, [], [1, 2, 3, 4, 5, 6]), - (1720572810.563889, [], [1, 2, 3, 4, 5, 6]), - (1720603175.70942, [], [1, 2, 3, 4, 5, 6]), - (1720603202.06502, [], [1, 2, 3, 4, 5, 6]), - (1720603204.156746, [], [1, 2, 3, 4, 5, 6]), - (1720652491.405509, [], [1, 2, 3, 4, 5, 6]), - (1720652598.039059, [], [1, 2, 3, 4, 5, 6]), - (1720652600.082367, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720153161.725292, [], [1, 2, 3, 4, 5, 6])], - [(1720494662.408865, [], [1, 2, 3, 4, 5, 6]), (1720568597.855422, [], [1, 2, 3, 4, 5, 6])], - [(1720416466.753208, [], [1, 2, 3, 4, 5, 6])], - [(1719978991.390168, [], [1, 2, 3, 4, 5, 6])], - [(1720072031.976782, [], [1, 2, 3, 4, 5, 6]), (1720584690.251602, [], [1, 2, 3, 4, 5, 6])], - [(1720575076.950008, [], [1, 2, 3, 4, 5, 6])], - [(1720231712.798613, [], [1, 2, 3, 4, 5, 6]), (1720398045.987903, [], [1, 2, 3, 4, 5, 6])], - [(1720056840.047309, [], [1, 2, 3, 4, 5, 6]), (1720625851.477544, [], [1, 2, 3, 4, 5, 6])], - [ - (1720053429.359158, [], [1, 2, 3, 4, 5, 6]), - (1720053508.29626, [], [1, 2, 3, 4, 5, 6]), - (1720053570.605172, [], [1, 2, 3, 4, 5, 6]), - (1720053639.380777, [], [1, 2, 3, 4, 5, 6]), - (1720066181.00997, [], [1, 2, 3, 4, 5, 6]), - (1720066215.053405, [], [1, 2, 3, 4, 5, 6]), - (1720066217.116517, [], [1, 2, 3, 4, 5, 6]), - (1720143779.66573, [], [1, 2, 3, 4, 5, 6]), - (1720143781.713526, [], [1, 2, 3, 4, 5, 6]), - (1720222105.35254, [], [1, 2, 3, 4, 5, 6]), - (1720317654.056711, [], [1, 2, 3, 4, 5, 6]), - (1720317708.563828, [], [1, 2, 3, 4, 5, 6]), - (1720480329.549535, [], [1, 2, 3, 4, 5, 6]), - (1720480520.417693, [], [1, 2, 3, 4, 5, 6]), - (1720480522.54519, [], [1, 2, 3, 4, 5, 6]), - (1720480523.499363, [], [1, 2, 3, 4, 5, 6]), - (1720577037.242221, [], [1, 2, 3, 4, 5, 6]), - (1720577039.306434, [], [1, 2, 3, 4, 5, 6]), - (1720639329.717862, [], [1, 2, 3, 4, 5, 6]), - (1720639469.331454, [], [1, 2, 3, 4, 5, 6]), - (1720639471.36127, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720024453.629276, [], [1, 2, 3, 4, 5, 6]), (1720316176.77774, [], [1, 2, 3, 4, 5, 6])], - [ - (1720068883.919311, [], [1, 2, 3, 4, 5, 6]), - (1720319773.101818, [], [1, 2, 3, 4, 5, 6]), - (1720586957.747953, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720056927.404781, [], [1, 2, 3, 4, 5, 6])], - [ - (1720054270.638059, [], [1, 2, 3, 4, 5, 6]), - (1720153565.870327, [], [1, 2, 3, 4, 5, 6]), - (1720334693.538652, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720152641.309698, [], [1, 2, 3, 4, 5, 6]), (1720576318.23299, [], [1, 2, 3, 4, 5, 6])], - [ - (1720404934.034946, [], [1, 2, 3, 4, 5, 6]), - (1720476937.980269, [], [1, 2, 3, 4, 5, 6]), - (1720652925.317718, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720583121.659416, [], [1, 2, 3, 4, 5, 6])], - [(1719974918.036807, [], [1, 2, 3, 4, 5, 6])], - [(1720052839.789235, [], [1, 2, 3, 4, 5, 6]), (1720309756.887443, [], [1, 2, 3, 4, 5, 6])], - [(1720214816.601474, [], [1, 2, 3, 4, 5, 6]), (1720628643.350003, [], [1, 2, 3, 4, 5, 6])], - [(1719990813.089809, [], [1, 2, 3, 4, 5, 6]), (1720312746.860016, [], [1, 2, 3, 4, 5, 6])], - [(1720072040.294779, [], [1, 2, 3, 4, 5, 6]), (1720573666.820699, [], [1, 2, 3, 4, 5, 6])], - [(1720221192.01312, [], [1, 2, 3, 4, 5, 6])], - [(1720143165.437476, [], [1, 2, 3, 4, 5, 6])], - [ - (1719965593.95106, [], [1, 2, 3, 4, 5, 6]), - (1720062861.422969, [], [1, 2, 3, 4, 5, 6]), - (1720503564.270709, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720310060.645551, [], [1, 2, 3, 4, 5, 6]), - (1720482309.217878, [], [1, 2, 3, 4, 5, 6]), - (1720591036.349001, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720157768.51272, [], [1, 2, 3, 4, 5, 6])], - [(1720149445.473387, [], [1, 2, 3, 4, 5, 6]), (1720438026.869011, [], [1, 2, 3, 4, 5, 6])], - [ - (1720060489.013219, [], [1, 2, 3, 4, 5, 6]), - (1720415886.629529, [], [1, 2, 3, 4, 5, 6]), - (1720580867.871164, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720414273.276015, [], [1, 2, 3, 4, 5, 6]), (1720487097.033528, [], [1, 2, 3, 4, 5, 6])], - [(1719966569.062726, [], [1, 2, 3, 4, 5, 6])], - [ - (1719966533.368239, [], [1, 2, 3, 4, 5, 6]), - (1720318867.369239, [], [1, 2, 3, 4, 5, 6]), - (1720424434.84027, [], [1, 2, 3, 4, 5, 6]), - (1720566607.607309, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720608001.068576, [], [1, 2, 3, 4, 5, 6])], - [ - (1720062804.379267, [], [1, 2, 3, 4, 5, 6]), - (1720226534.49236, [], [1, 2, 3, 4, 5, 6]), - (1720321084.499585, [], [1, 2, 3, 4, 5, 6]), - (1720450358.303395, [], [1, 2, 3, 4, 5, 6]), - (1720577114.020932, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720138095.209939, [], [1, 2, 3, 4, 5, 6])], - [ - (1720109654.682718, [], [1, 2, 3, 4, 5, 6]), - (1720109832.815741, [], [1, 2, 3, 4, 5, 6]), - (1720109959.88633, [], [1, 2, 3, 4, 5, 6]), - (1720110033.900336, [], [1, 2, 3, 4, 5, 6]), - (1720110090.159457, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719973270.54798, [], [1, 2, 3, 4, 5, 6])], - [(1720404747.93651, [], [1, 2, 3, 4, 5, 6])], - [(1719975896.00888, [], [1, 2, 3, 4, 5, 6]), (1720412877.994145, [], [1, 2, 3, 4, 5, 6])], - [(1720488415.324703, [], [1, 2, 3, 4, 5, 6])], - [ - (1719979329.168652, [], [1, 2, 3, 4, 5, 6]), - (1719979433.834943, [], [1, 2, 3, 4, 5, 6]), - (1719979537.706541, [], [1, 2, 3, 4, 5, 6]), - (1720054525.517489, [], [1, 2, 3, 4, 5, 6]), - (1720054576.808031, [], [1, 2, 3, 4, 5, 6]), - (1720054637.310552, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720008269.86362, [], [1, 2, 3, 4, 5, 6]), (1720228186.690288, [], [1, 2, 3, 4, 5, 6])], - [(1719980906.390651, [], [1, 2, 3, 4, 5, 6])], - [(1720049804.519108, [], [1, 2, 3, 4, 5, 6])], - [(1719982824.989151, [], [1, 2, 3, 4, 5, 6])], - [ - (1720052793.231176, [], [1, 2, 3, 4, 5, 6]), - (1720416383.522419, [], [1, 2, 3, 4, 5, 6]), - (1720576203.462386, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720141956.096351, [], [1, 2, 3, 4, 5, 6]), (1720501761.653384, [], [1, 2, 3, 4, 5, 6])], - [(1719968214.670337, [], [1, 2, 3, 4, 5, 6])], - [ - (1720061582.741936, [], [1, 2, 3, 4, 5, 6]), - (1720148352.805998, [], [1, 2, 3, 4, 5, 6]), - (1720320650.836088, [], [1, 2, 3, 4, 5, 6]), - (1720480540.757287, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720066746.296404, [], [1, 2, 3, 4, 5, 6]), (1720470635.779369, [], [1, 2, 3, 4, 5, 6])], - [(1720036143.99876, [], [1, 2, 3, 4, 5, 6]), (1720235115.25383, [], [1, 2, 3, 4, 5, 6])], - [ - (1720325739.301864, [], [1, 2, 3, 4, 5, 6]), - (1720366758.48691, [], [1, 2, 3, 4, 5, 6]), - (1720579671.285769, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720406674.612278, [], [1, 2, 3, 4, 5, 6])], - [(1720569843.609239, [], [1, 2, 3, 4, 5, 6])], - [ - (1720060843.491976, [], [1, 2, 3, 4, 5, 6]), - (1720147665.305258, [], [1, 2, 3, 4, 5, 6]), - (1720501529.904655, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720046373.265399, [], [1, 2, 3, 4, 5, 6]), - (1720046375.332994, [], [1, 2, 3, 4, 5, 6]), - (1720068144.411279, [], [1, 2, 3, 4, 5, 6]), - (1720068261.195225, [], [1, 2, 3, 4, 5, 6]), - (1720131629.331825, [], [1, 2, 3, 4, 5, 6]), - (1720131717.731289, [], [1, 2, 3, 4, 5, 6]), - (1720143208.108341, [], [1, 2, 3, 4, 5, 6]), - (1720224375.336718, [], [1, 2, 3, 4, 5, 6]), - (1720224489.89131, [], [1, 2, 3, 4, 5, 6]), - (1720239983.991454, [], [1, 2, 3, 4, 5, 6]), - (1720240023.957522, [], [1, 2, 3, 4, 5, 6]), - (1720240026.023994, [], [1, 2, 3, 4, 5, 6]), - (1720288870.449116, [], [1, 2, 3, 4, 5, 6]), - (1720319014.330473, [], [1, 2, 3, 4, 5, 6]), - (1720319153.071162, [], [1, 2, 3, 4, 5, 6]), - (1720319155.11854, [], [1, 2, 3, 4, 5, 6]), - (1720356008.754634, [], [1, 2, 3, 4, 5, 6]), - (1720356170.017209, [], [1, 2, 3, 4, 5, 6]), - (1720414281.753569, [], [1, 2, 3, 4, 5, 6]), - (1720466888.126284, [], [1, 2, 3, 4, 5, 6]), - (1720466890.175399, [], [1, 2, 3, 4, 5, 6]), - (1720496852.884055, [], [1, 2, 3, 4, 5, 6]), - (1720496900.157534, [], [1, 2, 3, 4, 5, 6]), - (1720496902.257177, [], [1, 2, 3, 4, 5, 6]), - (1720517711.484252, [], [1, 2, 3, 4, 5, 6]), - (1720517785.617389, [], [1, 2, 3, 4, 5, 6]), - (1720517787.722386, [], [1, 2, 3, 4, 5, 6]), - (1720574636.301281, [], [1, 2, 3, 4, 5, 6]), - (1720574638.402501, [], [1, 2, 3, 4, 5, 6]), - (1720631962.467861, [], [1, 2, 3, 4, 5, 6]), - (1720632073.350096, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720222983.951049, [], [1, 2, 3, 4, 5, 6]), (1720416117.193584, [], [1, 2, 3, 4, 5, 6])], - [ - (1719971140.695348, [], [1, 2, 3, 4, 5, 6]), - (1720135102.372106, [], [1, 2, 3, 4, 5, 6]), - (1720241528.560118, [], [1, 2, 3, 4, 5, 6]), - (1720494221.442123, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720321074.976216, [], [1, 2, 3, 4, 5, 6]), (1720409891.326419, [], [1, 2, 3, 4, 5, 6])], - [ - (1720048681.074873, [], [1, 2, 3, 4, 5, 6]), - (1720048799.279747, [], [1, 2, 3, 4, 5, 6]), - (1720048801.388645, [], [1, 2, 3, 4, 5, 6]), - (1720078114.283264, [], [1, 2, 3, 4, 5, 6]), - (1720078331.228227, [], [1, 2, 3, 4, 5, 6]), - (1720143813.123392, [], [1, 2, 3, 4, 5, 6]), - (1720143818.771163, [], [1, 2, 3, 4, 5, 6]), - (1720235193.521271, [], [1, 2, 3, 4, 5, 6]), - (1720235195.596896, [], [1, 2, 3, 4, 5, 6]), - (1720325140.395885, [], [1, 2, 3, 4, 5, 6]), - (1720325267.478348, [], [1, 2, 3, 4, 5, 6]), - (1720411316.426439, [], [1, 2, 3, 4, 5, 6]), - (1720411410.991238, [], [1, 2, 3, 4, 5, 6]), - (1720411413.049352, [], [1, 2, 3, 4, 5, 6]), - (1720585972.027756, [], [1, 2, 3, 4, 5, 6]), - (1720586043.355429, [], [1, 2, 3, 4, 5, 6]), - (1720586045.457795, [], [1, 2, 3, 4, 5, 6]), - (1720615162.541609, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719966754.275194, [], [1, 2, 3, 4, 5, 6]), - (1720490216.464205, [], [1, 2, 3, 4, 5, 6]), - (1720553382.681907, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720002644.294528, [], [1, 2, 3, 4, 5, 6]), (1720230090.842106, [], [1, 2, 3, 4, 5, 6])], - [(1720146769.696788, [], [1, 2, 3, 4, 5, 6])], - [ - (1720165756.310512, [], [1, 2, 3, 4, 5, 6]), - (1720410912.566749, [], [1, 2, 3, 4, 5, 6]), - (1720570647.832366, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719976353.576494, [], [1, 2, 3, 4, 5, 6]), - (1720377185.297147, [], [1, 2, 3, 4, 5, 6]), - (1720377289.215042, [], [1, 2, 3, 4, 5, 6]), - (1720377308.468995, [], [1, 2, 3, 4, 5, 6]), - (1720377428.407697, [], [1, 2, 3, 4, 5, 6]), - (1720377485.735576, [], [1, 2, 3, 4, 5, 6]), - (1720377529.508166, [], [1, 2, 3, 4, 5, 6]), - (1720377719.383399, [], [1, 2, 3, 4, 5, 6]), - (1720377809.666048, [], [1, 2, 3, 4, 5, 6]), - (1720377903.918773, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719980213.693083, [], [1, 2, 3, 4, 5, 6]), (1720140384.252931, [], [1, 2, 3, 4, 5, 6])], - [(1720063871.378525, [], [1, 2, 3, 4, 5, 6]), (1720573199.935932, [], [1, 2, 3, 4, 5, 6])], - [(1719985832.719319, [], [1, 2, 3, 4, 5, 6]), (1720406386.34727, [], [1, 2, 3, 4, 5, 6])], - [(1720235695.246766, [], [1, 2, 3, 4, 5, 6]), (1720397629.747797, [], [1, 2, 3, 4, 5, 6])], - [ - (1719968874.938189, [], [1, 2, 3, 4, 5, 6]), - (1719969009.652547, [], [1, 2, 3, 4, 5, 6]), - (1719985700.913806, [], [1, 2, 3, 4, 5, 6]), - (1719985791.512554, [], [1, 2, 3, 4, 5, 6]), - (1720148300.05719, [], [1, 2, 3, 4, 5, 6]), - (1720148304.627225, [], [1, 2, 3, 4, 5, 6]), - (1720148306.685703, [], [1, 2, 3, 4, 5, 6]), - (1720227741.213642, [], [1, 2, 3, 4, 5, 6]), - (1720227808.775173, [], [1, 2, 3, 4, 5, 6]), - (1720295172.811284, [], [1, 2, 3, 4, 5, 6]), - (1720295262.745855, [], [1, 2, 3, 4, 5, 6]), - (1720295264.827116, [], [1, 2, 3, 4, 5, 6]), - (1720295269.130924, [], [1, 2, 3, 4, 5, 6]), - (1720295271.214758, [], [1, 2, 3, 4, 5, 6]), - (1720295276.000757, [], [1, 2, 3, 4, 5, 6]), - (1720295278.050173, [], [1, 2, 3, 4, 5, 6]), - (1720295281.951474, [], [1, 2, 3, 4, 5, 6]), - (1720314791.722567, [], [1, 2, 3, 4, 5, 6]), - (1720314793.809493, [], [1, 2, 3, 4, 5, 6]), - (1720314794.091414, [], [1, 2, 3, 4, 5, 6]), - (1720314796.180282, [], [1, 2, 3, 4, 5, 6]), - (1720334621.693568, [], [1, 2, 3, 4, 5, 6]), - (1720334651.208509, [], [1, 2, 3, 4, 5, 6]), - (1720334653.289286, [], [1, 2, 3, 4, 5, 6]), - (1720405990.429231, [], [1, 2, 3, 4, 5, 6]), - (1720406072.368399, [], [1, 2, 3, 4, 5, 6]), - (1720406074.479232, [], [1, 2, 3, 4, 5, 6]), - (1720502938.778116, [], [1, 2, 3, 4, 5, 6]), - (1720502940.865312, [], [1, 2, 3, 4, 5, 6]), - (1720575136.293441, [], [1, 2, 3, 4, 5, 6]), - (1720575193.500487, [], [1, 2, 3, 4, 5, 6]), - (1720575195.593287, [], [1, 2, 3, 4, 5, 6]), - (1720584066.099625, [], [1, 2, 3, 4, 5, 6]), - (1720584068.181406, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720401234.664166, [], [1, 2, 3, 4, 5, 6])], - [(1720338995.593562, [], [1, 2, 3, 4, 5, 6]), (1720569421.058122, [], [1, 2, 3, 4, 5, 6])], - [ - (1720152780.103003, [], [1, 2, 3, 4, 5, 6]), - (1720318021.21162, [], [1, 2, 3, 4, 5, 6]), - (1720568682.771219, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720153767.474128, [], [1, 2, 3, 4, 5, 6]), - (1720153989.99445, [], [1, 2, 3, 4, 5, 6]), - (1720154117.339532, [], [1, 2, 3, 4, 5, 6]), - (1720154188.47243, [], [1, 2, 3, 4, 5, 6]), - (1720227169.047901, [], [1, 2, 3, 4, 5, 6]), - (1720227171.113334, [], [1, 2, 3, 4, 5, 6]), - (1720290328.719511, [], [1, 2, 3, 4, 5, 6]), - (1720290370.18464, [], [1, 2, 3, 4, 5, 6]), - (1720308949.583306, [], [1, 2, 3, 4, 5, 6]), - (1720309021.205367, [], [1, 2, 3, 4, 5, 6]), - (1720309023.255742, [], [1, 2, 3, 4, 5, 6]), - (1720400031.238045, [], [1, 2, 3, 4, 5, 6]), - (1720400050.534361, [], [1, 2, 3, 4, 5, 6]), - (1720400052.591865, [], [1, 2, 3, 4, 5, 6]), - (1720475517.057002, [], [1, 2, 3, 4, 5, 6]), - (1720475631.221119, [], [1, 2, 3, 4, 5, 6]), - (1720489341.891834, [], [1, 2, 3, 4, 5, 6]), - (1720489520.813888, [], [1, 2, 3, 4, 5, 6]), - (1720522911.41822, [], [1, 2, 3, 4, 5, 6]), - (1720522980.415637, [], [1, 2, 3, 4, 5, 6]), - (1720522982.44762, [], [1, 2, 3, 4, 5, 6]), - (1720590435.585175, [], [1, 2, 3, 4, 5, 6]), - (1720590601.259611, [], [1, 2, 3, 4, 5, 6]), - (1720590603.315457, [], [1, 2, 3, 4, 5, 6]), - (1720590604.638539, [], [1, 2, 3, 4, 5, 6]), - (1720590606.730642, [], [1, 2, 3, 4, 5, 6]), - (1720612053.860624, [], [1, 2, 3, 4, 5, 6]), - (1720612129.921877, [], [1, 2, 3, 4, 5, 6]), - (1720612132.011818, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720426949.173587, [], [1, 2, 3, 4, 5, 6])], - [(1720569102.034496, [], [1, 2, 3, 4, 5, 6])], - [(1720034790.744638, [], [1, 2, 3, 4, 5, 6]), (1720307075.973997, [], [1, 2, 3, 4, 5, 6])], - [ - (1720226287.705985, [], [1, 2, 3, 4, 5, 6]), - (1720397684.607266, [], [1, 2, 3, 4, 5, 6]), - (1720488997.884315, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720228730.18975, [], [1, 2, 3, 4, 5, 6]), - (1720407495.769529, [], [1, 2, 3, 4, 5, 6]), - (1720486995.921451, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720489080.310875, [], [1, 2, 3, 4, 5, 6]), (1720579311.992295, [], [1, 2, 3, 4, 5, 6])], - [(1720138007.433538, [], [1, 2, 3, 4, 5, 6]), (1720243741.609597, [], [1, 2, 3, 4, 5, 6])], - [(1720528666.459324, [], [1, 2, 3, 4, 5, 6])], - [(1719970772.701878, [], [1, 2, 3, 4, 5, 6]), (1720141632.061506, [], [1, 2, 3, 4, 5, 6])], - [(1720068110.038208, [], [1, 2, 3, 4, 5, 6])], - [(1720047191.032235, [], [1, 2, 3, 4, 5, 6])], - [(1719976436.118248, [], [1, 2, 3, 4, 5, 6]), (1720307037.853977, [], [1, 2, 3, 4, 5, 6])], - [(1719972036.639217, [], [1, 2, 3, 4, 5, 6]), (1720057689.829017, [], [1, 2, 3, 4, 5, 6])], - [(1720110461.39165, [], [1, 2, 3, 4, 5, 6]), (1720507249.36072, [], [1, 2, 3, 4, 5, 6])], - [(1719973197.847086, [], [1, 2, 3, 4, 5, 6])], - [ - (1720069338.721539, [], [1, 2, 3, 4, 5, 6]), - (1720524537.017222, [], [1, 2, 3, 4, 5, 6]), - (1720603176.268707, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720142471.621654, [], [1, 2, 3, 4, 5, 6]), (1720221877.173433, [], [1, 2, 3, 4, 5, 6])], - [(1720141771.947396, [], [1, 2, 3, 4, 5, 6])], - [(1720563222.366935, [], [1, 2, 3, 4, 5, 6])], - [(1720237444.558492, [], [1, 2, 3, 4, 5, 6]), (1720586951.821255, [], [1, 2, 3, 4, 5, 6])], - [ - (1720066787.226665, [], [1, 2, 3, 4, 5, 6]), - (1720138501.376918, [], [1, 2, 3, 4, 5, 6]), - (1720332897.490345, [], [1, 2, 3, 4, 5, 6]), - (1720498267.095353, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719979972.999784, [], [1, 2, 3, 4, 5, 6]), (1720326547.318274, [], [1, 2, 3, 4, 5, 6])], - [(1720156142.458551, [], [1, 2, 3, 4, 5, 6]), (1720222674.830191, [], [1, 2, 3, 4, 5, 6])], - [ - (1719976247.399205, [], [1, 2, 3, 4, 5, 6]), - (1719976421.138728, [], [1, 2, 3, 4, 5, 6]), - (1719976457.121053, [], [1, 2, 3, 4, 5, 6]), - (1719976566.522486, [], [1, 2, 3, 4, 5, 6]), - (1720060116.807539, [], [1, 2, 3, 4, 5, 6]), - (1720142201.528128, [], [1, 2, 3, 4, 5, 6]), - (1720142320.790244, [], [1, 2, 3, 4, 5, 6]), - (1720142322.873716, [], [1, 2, 3, 4, 5, 6]), - (1720142323.209429, [], [1, 2, 3, 4, 5, 6]), - (1720142325.32365, [], [1, 2, 3, 4, 5, 6]), - (1720158309.47212, [], [1, 2, 3, 4, 5, 6]), - (1720158464.699924, [], [1, 2, 3, 4, 5, 6]), - (1720158466.803077, [], [1, 2, 3, 4, 5, 6]), - (1720235827.780639, [], [1, 2, 3, 4, 5, 6]), - (1720235829.873017, [], [1, 2, 3, 4, 5, 6]), - (1720235831.516786, [], [1, 2, 3, 4, 5, 6]), - (1720235833.64015, [], [1, 2, 3, 4, 5, 6]), - (1720308111.792929, [], [1, 2, 3, 4, 5, 6]), - (1720308113.917634, [], [1, 2, 3, 4, 5, 6]), - (1720330424.153222, [], [1, 2, 3, 4, 5, 6]), - (1720330426.274619, [], [1, 2, 3, 4, 5, 6]), - (1720397440.529792, [], [1, 2, 3, 4, 5, 6]), - (1720397517.527169, [], [1, 2, 3, 4, 5, 6]), - (1720397519.567891, [], [1, 2, 3, 4, 5, 6]), - (1720489794.692916, [], [1, 2, 3, 4, 5, 6]), - (1720489888.559008, [], [1, 2, 3, 4, 5, 6]), - (1720489890.678539, [], [1, 2, 3, 4, 5, 6]), - (1720577363.385966, [], [1, 2, 3, 4, 5, 6]), - (1720577493.034855, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720042932.668232, [], [1, 2, 3, 4, 5, 6])], - [ - (1720059740.224971, [], [1, 2, 3, 4, 5, 6]), - (1720141837.883794, [], [1, 2, 3, 4, 5, 6]), - (1720405792.751871, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720050443.838424, [], [1, 2, 3, 4, 5, 6]), (1720124719.146549, [], [1, 2, 3, 4, 5, 6])], - [(1719974887.67444, [], [1, 2, 3, 4, 5, 6]), (1720568466.68215, [], [1, 2, 3, 4, 5, 6])], - [(1720065592.314345, [], [1, 2, 3, 4, 5, 6]), (1720205463.888972, [], [1, 2, 3, 4, 5, 6])], - [ - (1720226332.701569, [], [1, 2, 3, 4, 5, 6]), - (1720396620.155135, [], [1, 2, 3, 4, 5, 6]), - (1720492327.218299, [], [1, 2, 3, 4, 5, 6]), - (1720574416.447233, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720045016.618738, [], [1, 2, 3, 4, 5, 6])], - [ - (1720041923.403398, [], [1, 2, 3, 4, 5, 6]), - (1720041925.529856, [], [1, 2, 3, 4, 5, 6]), - (1720041929.344695, [], [1, 2, 3, 4, 5, 6]), - (1720071082.001532, [], [1, 2, 3, 4, 5, 6]), - (1720071201.167727, [], [1, 2, 3, 4, 5, 6]), - (1720071203.259989, [], [1, 2, 3, 4, 5, 6]), - (1720113938.478909, [], [1, 2, 3, 4, 5, 6]), - (1720114019.141219, [], [1, 2, 3, 4, 5, 6]), - (1720147954.114345, [], [1, 2, 3, 4, 5, 6]), - (1720148058.186186, [], [1, 2, 3, 4, 5, 6]), - (1720148060.244565, [], [1, 2, 3, 4, 5, 6]), - (1720230463.28606, [], [1, 2, 3, 4, 5, 6]), - (1720230465.339869, [], [1, 2, 3, 4, 5, 6]), - (1720306384.513301, [], [1, 2, 3, 4, 5, 6]), - (1720306386.603107, [], [1, 2, 3, 4, 5, 6]), - (1720327575.975525, [], [1, 2, 3, 4, 5, 6]), - (1720327821.751969, [], [1, 2, 3, 4, 5, 6]), - (1720327823.781901, [], [1, 2, 3, 4, 5, 6]), - (1720410348.159738, [], [1, 2, 3, 4, 5, 6]), - (1720410448.341114, [], [1, 2, 3, 4, 5, 6]), - (1720457570.237639, [], [1, 2, 3, 4, 5, 6]), - (1720457731.119754, [], [1, 2, 3, 4, 5, 6]), - (1720457733.248545, [], [1, 2, 3, 4, 5, 6]), - (1720499264.385485, [], [1, 2, 3, 4, 5, 6]), - (1720499470.033411, [], [1, 2, 3, 4, 5, 6]), - (1720499472.085357, [], [1, 2, 3, 4, 5, 6]), - (1720543986.94937, [], [1, 2, 3, 4, 5, 6]), - (1720570525.581032, [], [1, 2, 3, 4, 5, 6]), - (1720570749.619565, [], [1, 2, 3, 4, 5, 6]), - (1720585164.854344, [], [1, 2, 3, 4, 5, 6]), - (1720585249.748529, [], [1, 2, 3, 4, 5, 6]), - (1720585251.810485, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720489237.597076, [], [1, 2, 3, 4, 5, 6]), - (1720489298.656835, [], [1, 2, 3, 4, 5, 6]), - (1720489340.853931, [], [1, 2, 3, 4, 5, 6]), - (1720489414.715662, [], [1, 2, 3, 4, 5, 6]), - (1720489578.362748, [], [1, 2, 3, 4, 5, 6]), - (1720489722.080922, [], [1, 2, 3, 4, 5, 6]), - (1720489846.161597, [], [1, 2, 3, 4, 5, 6]), - (1720489902.616032, [], [1, 2, 3, 4, 5, 6]), - (1720489979.179271, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720226541.700259, [], [1, 2, 3, 4, 5, 6]), (1720459357.712795, [], [1, 2, 3, 4, 5, 6])], - [ - (1720137147.179349, [], [1, 2, 3, 4, 5, 6]), - (1720241160.346244, [], [1, 2, 3, 4, 5, 6]), - (1720393844.000636, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720233961.944441, [], [1, 2, 3, 4, 5, 6]), (1720475993.227865, [], [1, 2, 3, 4, 5, 6])], - [(1720339946.523179, [], [1, 2, 3, 4, 5, 6])], - [(1720314335.142585, [], [1, 2, 3, 4, 5, 6])], - [(1720307070.122528, [], [1, 2, 3, 4, 5, 6]), (1720396806.823553, [], [1, 2, 3, 4, 5, 6])], - [(1720134885.254524, [], [1, 2, 3, 4, 5, 6]), (1720582472.172677, [], [1, 2, 3, 4, 5, 6])], - [ - (1720064989.52196, [], [1, 2, 3, 4, 5, 6]), - (1720317471.54011, [], [1, 2, 3, 4, 5, 6]), - (1720405569.646675, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720230240.375249, [], [1, 2, 3, 4, 5, 6])], - [ - (1719981989.67667, [], [1, 2, 3, 4, 5, 6]), - (1719982209.356573, [], [1, 2, 3, 4, 5, 6]), - (1719982211.412871, [], [1, 2, 3, 4, 5, 6]), - (1719990729.511533, [], [1, 2, 3, 4, 5, 6]), - (1719990731.571772, [], [1, 2, 3, 4, 5, 6]), - (1720052018.486278, [], [1, 2, 3, 4, 5, 6]), - (1720052084.895512, [], [1, 2, 3, 4, 5, 6]), - (1720052086.959136, [], [1, 2, 3, 4, 5, 6]), - (1720063752.458627, [], [1, 2, 3, 4, 5, 6]), - (1720063775.402517, [], [1, 2, 3, 4, 5, 6]), - (1720131365.952047, [], [1, 2, 3, 4, 5, 6]), - (1720131512.217778, [], [1, 2, 3, 4, 5, 6]), - (1720131514.344434, [], [1, 2, 3, 4, 5, 6]), - (1720155954.588913, [], [1, 2, 3, 4, 5, 6]), - (1720156049.221823, [], [1, 2, 3, 4, 5, 6]), - (1720326057.45718, [], [1, 2, 3, 4, 5, 6]), - (1720404760.882693, [], [1, 2, 3, 4, 5, 6]), - (1720404806.729924, [], [1, 2, 3, 4, 5, 6]), - (1720404808.834418, [], [1, 2, 3, 4, 5, 6]), - (1720416517.018963, [], [1, 2, 3, 4, 5, 6]), - (1720494367.532053, [], [1, 2, 3, 4, 5, 6]), - (1720500247.551019, [], [1, 2, 3, 4, 5, 6]), - (1720500294.606063, [], [1, 2, 3, 4, 5, 6]), - (1720500296.694825, [], [1, 2, 3, 4, 5, 6]), - (1720500299.259697, [], [1, 2, 3, 4, 5, 6]), - (1720500301.365635, [], [1, 2, 3, 4, 5, 6]), - (1720572338.244531, [], [1, 2, 3, 4, 5, 6]), - (1720572428.794186, [], [1, 2, 3, 4, 5, 6]), - (1720572430.860491, [], [1, 2, 3, 4, 5, 6]), - (1720600877.354363, [], [1, 2, 3, 4, 5, 6]), - (1720601092.109844, [], [1, 2, 3, 4, 5, 6]), - (1720601094.164843, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720230142.987461, [], [1, 2, 3, 4, 5, 6])], - [(1720040834.068992, [], [1, 2, 3, 4, 5, 6])], - [ - (1719984036.646786, [], [1, 2, 3, 4, 5, 6]), - (1720138775.775437, [], [1, 2, 3, 4, 5, 6]), - (1720337436.06649, [], [1, 2, 3, 4, 5, 6]), - (1720567415.54222, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720501680.278938, [], [1, 2, 3, 4, 5, 6]), (1720645969.459141, [], [1, 2, 3, 4, 5, 6])], - [(1719981148.135955, [], [1, 2, 3, 4, 5, 6]), (1720574648.013669, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982323.222591, [], [1, 2, 3, 4, 5, 6]), - (1720101646.380659, [], [1, 2, 3, 4, 5, 6]), - (1720493833.121559, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977634.84991, [], [1, 2, 3, 4, 5, 6])], - [(1720494761.805988, [], [1, 2, 3, 4, 5, 6]), (1720595943.849674, [], [1, 2, 3, 4, 5, 6])], - [ - (1720155432.624618, [], [1, 2, 3, 4, 5, 6]), - (1720500643.020756, [], [1, 2, 3, 4, 5, 6]), - (1720584683.624928, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720245035.196003, [], [1, 2, 3, 4, 5, 6])], - [(1720313673.855042, [], [1, 2, 3, 4, 5, 6]), (1720381149.495776, [], [1, 2, 3, 4, 5, 6])], - [(1720019520.657419, [], [1, 2, 3, 4, 5, 6])], - [(1719981920.434976, [], [1, 2, 3, 4, 5, 6]), (1720128572.036838, [], [1, 2, 3, 4, 5, 6])], - [(1720136202.220094, [], [1, 2, 3, 4, 5, 6]), (1720279940.922158, [], [1, 2, 3, 4, 5, 6])], - [(1720462395.987553, [], [1, 2, 3, 4, 5, 6])], - [ - (1720653383.244, [], [1, 2, 3, 4, 5, 6]), - (1720653383.325, [], [1, 2, 3, 4, 5, 6]), - (1720653391.627, [], [1, 2, 3, 4, 5, 6]), - (1720653392.102, [], [1, 2, 3, 4, 5, 6]), - (1720653392.298, [], [1, 2, 3, 4, 5, 6]), - (1720653394.934, [], [1, 2, 3, 4, 5, 6]), - (1720653396.411, [], [1, 2, 3, 4, 5, 6]), - (1720653433.093, [], [1, 2, 3, 4, 5, 6]), - (1720653433.236, [], [1, 2, 3, 4, 5, 6]), - (1720653434.991, [], [1, 2, 3, 4, 5, 6]), - (1720653435.037, [], [1, 2, 3, 4, 5, 6]), - (1720653501.654, [], [1, 2, 3, 4, 5, 6]), - (1720653501.71, [], [1, 2, 3, 4, 5, 6]), - (1720653504.799, [], [1, 2, 3, 4, 5, 6]), - (1720653506.446, [], [1, 2, 3, 4, 5, 6]), - (1720653507.872, [], [1, 2, 3, 4, 5, 6]), - (1720654003.023, [], [1, 2, 3, 4, 5, 6]), - (1720654003.148, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719977539.575178, [], [1, 2, 3, 4, 5, 6]), - (1720223726.13705, [], [1, 2, 3, 4, 5, 6]), - (1720396336.894644, [], [1, 2, 3, 4, 5, 6]), - (1720587683.68083, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720327049.710872, [], [1, 2, 3, 4, 5, 6])], - [(1720223003.678086, [], [1, 2, 3, 4, 5, 6]), (1720320656.874702, [], [1, 2, 3, 4, 5, 6])], - [(1720149475.628567, [], [1, 2, 3, 4, 5, 6]), (1720228859.277837, [], [1, 2, 3, 4, 5, 6])], - [(1720049864.230497, [], [1, 2, 3, 4, 5, 6])], - [(1720198432.201466, [], [1, 2, 3, 4, 5, 6])], - [ - (1719975613.439717, [], [1, 2, 3, 4, 5, 6]), - (1719975648.049123, [], [1, 2, 3, 4, 5, 6]), - (1720056914.90013, [], [1, 2, 3, 4, 5, 6]), - (1720057026.542911, [], [1, 2, 3, 4, 5, 6]), - (1720061926.526142, [], [1, 2, 3, 4, 5, 6]), - (1720062007.614611, [], [1, 2, 3, 4, 5, 6]), - (1720147419.43368, [], [1, 2, 3, 4, 5, 6]), - (1720147421.485277, [], [1, 2, 3, 4, 5, 6]), - (1720234139.651394, [], [1, 2, 3, 4, 5, 6]), - (1720234141.758276, [], [1, 2, 3, 4, 5, 6]), - (1720315191.984726, [], [1, 2, 3, 4, 5, 6]), - (1720315194.093018, [], [1, 2, 3, 4, 5, 6]), - (1720315195.836394, [], [1, 2, 3, 4, 5, 6]), - (1720395738.54726, [], [1, 2, 3, 4, 5, 6]), - (1720395740.684533, [], [1, 2, 3, 4, 5, 6]), - (1720410342.218884, [], [1, 2, 3, 4, 5, 6]), - (1720410455.568303, [], [1, 2, 3, 4, 5, 6]), - (1720496479.412713, [], [1, 2, 3, 4, 5, 6]), - (1720496636.329168, [], [1, 2, 3, 4, 5, 6]), - (1720568810.362519, [], [1, 2, 3, 4, 5, 6]), - (1720569040.475975, [], [1, 2, 3, 4, 5, 6]), - (1720652557.884167, [], [1, 2, 3, 4, 5, 6]), - (1720652630.129755, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720233899.203213, [], [1, 2, 3, 4, 5, 6]), - (1720463796.00711, [], [1, 2, 3, 4, 5, 6]), - (1720567454.878169, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720218589.331391, [], [1, 2, 3, 4, 5, 6]), - (1720572246.733219, [], [1, 2, 3, 4, 5, 6]), - (1720585861.133309, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720030179.060188, [], [1, 2, 3, 4, 5, 6]), - (1720330759.17762, [], [1, 2, 3, 4, 5, 6]), - (1720494515.69797, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719979902.797865, [], [1, 2, 3, 4, 5, 6])], - [ - (1720070638.173492, [], [1, 2, 3, 4, 5, 6]), - (1720070819.083453, [], [1, 2, 3, 4, 5, 6]), - (1720070899.802295, [], [1, 2, 3, 4, 5, 6]), - (1720318683.767078, [], [1, 2, 3, 4, 5, 6]), - (1720318886.533145, [], [1, 2, 3, 4, 5, 6]), - (1720318966.57212, [], [1, 2, 3, 4, 5, 6]), - (1720318995.968059, [], [1, 2, 3, 4, 5, 6]), - (1720319139.50433, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720146380.443011, [], [1, 2, 3, 4, 5, 6]), (1720567703.854081, [], [1, 2, 3, 4, 5, 6])], - [(1720485224.936769, [], [1, 2, 3, 4, 5, 6])], - [(1720039180.636756, [], [1, 2, 3, 4, 5, 6]), (1720320703.675688, [], [1, 2, 3, 4, 5, 6])], - [(1720572877.111346, [], [1, 2, 3, 4, 5, 6])], - [(1720149009.624794, [], [1, 2, 3, 4, 5, 6])], - [ - (1720146066.037668, [], [1, 2, 3, 4, 5, 6]), - (1720233446.585623, [], [1, 2, 3, 4, 5, 6]), - (1720397647.223612, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720071535.98588, [], [1, 2, 3, 4, 5, 6]), - (1720222696.675857, [], [1, 2, 3, 4, 5, 6]), - (1720581710.534385, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720320564.297259, [], [1, 2, 3, 4, 5, 6])], - [(1720221596.179609, [], [1, 2, 3, 4, 5, 6]), (1720502714.197196, [], [1, 2, 3, 4, 5, 6])], - [(1720553799.408143, [], [1, 2, 3, 4, 5, 6])], - [ - (1720244362.654861, [], [1, 2, 3, 4, 5, 6]), - (1720412405.21556, [], [1, 2, 3, 4, 5, 6]), - (1720566429.648086, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720225993.003411, [], [1, 2, 3, 4, 5, 6]), (1720576860.143664, [], [1, 2, 3, 4, 5, 6])], - [(1720050680.82043, [], [1, 2, 3, 4, 5, 6])], - [(1719979231.190542, [], [1, 2, 3, 4, 5, 6]), (1720395944.084001, [], [1, 2, 3, 4, 5, 6])], - [(1720483644.896944, [], [1, 2, 3, 4, 5, 6])], - [ - (1720238837.512808, [], [1, 2, 3, 4, 5, 6]), - (1720400917.965225, [], [1, 2, 3, 4, 5, 6]), - (1720499924.896186, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978670.650293, [], [1, 2, 3, 4, 5, 6]), (1720312908.844749, [], [1, 2, 3, 4, 5, 6])], - [ - (1720064475.615309, [], [1, 2, 3, 4, 5, 6]), - (1720311005.200102, [], [1, 2, 3, 4, 5, 6]), - (1720398033.682041, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974842.261587, [], [1, 2, 3, 4, 5, 6]), - (1720070482.809945, [], [1, 2, 3, 4, 5, 6]), - (1720492054.306253, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719985346.86067, [], [1, 2, 3, 4, 5, 6])], - [(1720494586.311794, [], [1, 2, 3, 4, 5, 6])], - [ - (1720151598.2787, [], [1, 2, 3, 4, 5, 6]), - (1720243336.399964, [], [1, 2, 3, 4, 5, 6]), - (1720394460.006175, [], [1, 2, 3, 4, 5, 6]), - (1720584803.786632, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720044414.812182, [], [1, 2, 3, 4, 5, 6]), (1720161374.32603, [], [1, 2, 3, 4, 5, 6])], - [(1720242818.837344, [], [1, 2, 3, 4, 5, 6])], - [(1720407806.948096, [], [1, 2, 3, 4, 5, 6]), (1720511793.967125, [], [1, 2, 3, 4, 5, 6])], - [(1720177465.166679, [], [1, 2, 3, 4, 5, 6])], - [(1720152899.613121, [], [1, 2, 3, 4, 5, 6])], - [(1720144169.768087, [], [1, 2, 3, 4, 5, 6])], - [(1720050900.326256, [], [1, 2, 3, 4, 5, 6]), (1720592651.789908, [], [1, 2, 3, 4, 5, 6])], - [(1720136535.399876, [], [1, 2, 3, 4, 5, 6]), (1720345016.561725, [], [1, 2, 3, 4, 5, 6])], - [(1720148677.039505, [], [1, 2, 3, 4, 5, 6])], - [(1720103982.765975, [], [1, 2, 3, 4, 5, 6]), (1720223275.492349, [], [1, 2, 3, 4, 5, 6])], - [(1719966246.265247, [], [1, 2, 3, 4, 5, 6])], - [(1720048787.249996, [], [1, 2, 3, 4, 5, 6]), (1720588475.186395, [], [1, 2, 3, 4, 5, 6])], - [ - (1720406823.932911, [], [1, 2, 3, 4, 5, 6]), - (1720406854.864424, [], [1, 2, 3, 4, 5, 6]), - (1720406898.943281, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720106989.608336, [], [1, 2, 3, 4, 5, 6])], - [(1719965156.233365, [], [1, 2, 3, 4, 5, 6]), (1720156113.65034, [], [1, 2, 3, 4, 5, 6])], - [(1720237894.767081, [], [1, 2, 3, 4, 5, 6])], - [ - (1720236335.89358, [], [1, 2, 3, 4, 5, 6]), - (1720311377.453215, [], [1, 2, 3, 4, 5, 6]), - (1720406308.416613, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720580297.715893, [], [1, 2, 3, 4, 5, 6])], - [(1719983515.156201, [], [1, 2, 3, 4, 5, 6]), (1720243011.26844, [], [1, 2, 3, 4, 5, 6])], - [(1720412740.206646, [], [1, 2, 3, 4, 5, 6])], - [(1720573676.882026, [], [1, 2, 3, 4, 5, 6])], - [(1720069113.016836, [], [1, 2, 3, 4, 5, 6])], - [(1720065156.88711, [], [1, 2, 3, 4, 5, 6]), (1720342013.62189, [], [1, 2, 3, 4, 5, 6])], - [(1720414414.37316, [], [1, 2, 3, 4, 5, 6]), (1720576057.542994, [], [1, 2, 3, 4, 5, 6])], - [ - (1719965980.977528, [], [1, 2, 3, 4, 5, 6]), - (1720328208.291947, [], [1, 2, 3, 4, 5, 6]), - (1720586256.843288, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719993285.557781, [], [1, 2, 3, 4, 5, 6])], - [ - (1720157474.360894, [], [1, 2, 3, 4, 5, 6]), - (1720317049.692797, [], [1, 2, 3, 4, 5, 6]), - (1720418157.354486, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720492206.117992, [], [1, 2, 3, 4, 5, 6])], - [(1720566094.344648, [], [1, 2, 3, 4, 5, 6])], - [(1719974058.930323, [], [1, 2, 3, 4, 5, 6]), (1720059173.893018, [], [1, 2, 3, 4, 5, 6])], - [(1720517061.661773, [], [1, 2, 3, 4, 5, 6])], - [(1720052300.009912, [], [1, 2, 3, 4, 5, 6]), (1720447926.535749, [], [1, 2, 3, 4, 5, 6])], - [(1720060153.321408, [], [1, 2, 3, 4, 5, 6]), (1720498576.79341, [], [1, 2, 3, 4, 5, 6])], - [(1720415193.154478, [], [1, 2, 3, 4, 5, 6]), (1720494529.74019, [], [1, 2, 3, 4, 5, 6])], - [ - (1719980354.732889, [], [1, 2, 3, 4, 5, 6]), - (1719980356.852338, [], [1, 2, 3, 4, 5, 6]), - (1719980359.805901, [], [1, 2, 3, 4, 5, 6]), - (1719980361.898886, [], [1, 2, 3, 4, 5, 6]), - (1719980364.204398, [], [1, 2, 3, 4, 5, 6]), - (1720063622.210305, [], [1, 2, 3, 4, 5, 6]), - (1720063766.011158, [], [1, 2, 3, 4, 5, 6]), - (1720063768.060823, [], [1, 2, 3, 4, 5, 6]), - (1720134932.57792, [], [1, 2, 3, 4, 5, 6]), - (1720148426.91756, [], [1, 2, 3, 4, 5, 6]), - (1720148428.987966, [], [1, 2, 3, 4, 5, 6]), - (1720237634.85931, [], [1, 2, 3, 4, 5, 6]), - (1720237687.961173, [], [1, 2, 3, 4, 5, 6]), - (1720321596.679301, [], [1, 2, 3, 4, 5, 6]), - (1720394727.592533, [], [1, 2, 3, 4, 5, 6]), - (1720394743.278857, [], [1, 2, 3, 4, 5, 6]), - (1720408408.443408, [], [1, 2, 3, 4, 5, 6]), - (1720419213.527306, [], [1, 2, 3, 4, 5, 6]), - (1720419321.981, [], [1, 2, 3, 4, 5, 6]), - (1720419324.073269, [], [1, 2, 3, 4, 5, 6]), - (1720497577.385151, [], [1, 2, 3, 4, 5, 6]), - (1720497694.789568, [], [1, 2, 3, 4, 5, 6]), - (1720497696.883431, [], [1, 2, 3, 4, 5, 6]), - (1720584999.597212, [], [1, 2, 3, 4, 5, 6]), - (1720585001.687849, [], [1, 2, 3, 4, 5, 6]), - (1720585005.063862, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720134251.830614, [], [1, 2, 3, 4, 5, 6]), - (1720407054.526951, [], [1, 2, 3, 4, 5, 6]), - (1720543564.686466, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720395362.215692, [], [1, 2, 3, 4, 5, 6]), (1720500480.122778, [], [1, 2, 3, 4, 5, 6])], - [ - (1720058412.695383, [], [1, 2, 3, 4, 5, 6]), - (1720228775.865928, [], [1, 2, 3, 4, 5, 6]), - (1720503282.31697, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720614350.980502, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982519.149294, [], [1, 2, 3, 4, 5, 6]), - (1719982589.903207, [], [1, 2, 3, 4, 5, 6]), - (1719982591.966235, [], [1, 2, 3, 4, 5, 6]), - (1719982594.824529, [], [1, 2, 3, 4, 5, 6]), - (1720056059.106374, [], [1, 2, 3, 4, 5, 6]), - (1720056099.353137, [], [1, 2, 3, 4, 5, 6]), - (1720056101.438857, [], [1, 2, 3, 4, 5, 6]), - (1720084141.137944, [], [1, 2, 3, 4, 5, 6]), - (1720084195.578773, [], [1, 2, 3, 4, 5, 6]), - (1720136869.202173, [], [1, 2, 3, 4, 5, 6]), - (1720223064.342828, [], [1, 2, 3, 4, 5, 6]), - (1720223120.591787, [], [1, 2, 3, 4, 5, 6]), - (1720223122.696149, [], [1, 2, 3, 4, 5, 6]), - (1720239556.237398, [], [1, 2, 3, 4, 5, 6]), - (1720239630.045363, [], [1, 2, 3, 4, 5, 6]), - (1720239632.137037, [], [1, 2, 3, 4, 5, 6]), - (1720312988.468776, [], [1, 2, 3, 4, 5, 6]), - (1720313161.594176, [], [1, 2, 3, 4, 5, 6]), - (1720313163.656358, [], [1, 2, 3, 4, 5, 6]), - (1720413652.862676, [], [1, 2, 3, 4, 5, 6]), - (1720413773.395596, [], [1, 2, 3, 4, 5, 6]), - (1720484458.010065, [], [1, 2, 3, 4, 5, 6]), - (1720484503.114542, [], [1, 2, 3, 4, 5, 6]), - (1720484505.173957, [], [1, 2, 3, 4, 5, 6]), - (1720570920.862746, [], [1, 2, 3, 4, 5, 6]), - (1720571065.994777, [], [1, 2, 3, 4, 5, 6]), - (1720571068.086575, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720138634.579801, [], [1, 2, 3, 4, 5, 6]), (1720394701.653755, [], [1, 2, 3, 4, 5, 6])], - [(1720404840.88735, [], [1, 2, 3, 4, 5, 6]), (1720570759.329975, [], [1, 2, 3, 4, 5, 6])], - [(1720474997.255842, [], [1, 2, 3, 4, 5, 6])], - [ - (1719964981.812038, [], [1, 2, 3, 4, 5, 6]), - (1719965079.656724, [], [1, 2, 3, 4, 5, 6]), - (1719965081.766625, [], [1, 2, 3, 4, 5, 6]), - (1720017945.346535, [], [1, 2, 3, 4, 5, 6]), - (1720018196.228851, [], [1, 2, 3, 4, 5, 6]), - (1720018198.332037, [], [1, 2, 3, 4, 5, 6]), - (1720071944.789981, [], [1, 2, 3, 4, 5, 6]), - (1720071989.860765, [], [1, 2, 3, 4, 5, 6]), - (1720071991.963241, [], [1, 2, 3, 4, 5, 6]), - (1720226601.357382, [], [1, 2, 3, 4, 5, 6]), - (1720226662.671017, [], [1, 2, 3, 4, 5, 6]), - (1720226664.720854, [], [1, 2, 3, 4, 5, 6]), - (1720226666.697991, [], [1, 2, 3, 4, 5, 6]), - (1720245432.525672, [], [1, 2, 3, 4, 5, 6]), - (1720245586.690365, [], [1, 2, 3, 4, 5, 6]), - (1720245588.811888, [], [1, 2, 3, 4, 5, 6]), - (1720313288.75101, [], [1, 2, 3, 4, 5, 6]), - (1720313438.935319, [], [1, 2, 3, 4, 5, 6]), - (1720313440.997298, [], [1, 2, 3, 4, 5, 6]), - (1720325185.461926, [], [1, 2, 3, 4, 5, 6]), - (1720325279.708469, [], [1, 2, 3, 4, 5, 6]), - (1720325281.823994, [], [1, 2, 3, 4, 5, 6]), - (1720325284.895173, [], [1, 2, 3, 4, 5, 6]), - (1720325286.963747, [], [1, 2, 3, 4, 5, 6]), - (1720351212.007507, [], [1, 2, 3, 4, 5, 6]), - (1720351417.722923, [], [1, 2, 3, 4, 5, 6]), - (1720351419.786979, [], [1, 2, 3, 4, 5, 6]), - (1720410234.644402, [], [1, 2, 3, 4, 5, 6]), - (1720410236.746729, [], [1, 2, 3, 4, 5, 6]), - (1720484087.598816, [], [1, 2, 3, 4, 5, 6]), - (1720484089.656452, [], [1, 2, 3, 4, 5, 6]), - (1720560975.588946, [], [1, 2, 3, 4, 5, 6]), - (1720561062.767708, [], [1, 2, 3, 4, 5, 6]), - (1720576170.001406, [], [1, 2, 3, 4, 5, 6]), - (1720576274.339938, [], [1, 2, 3, 4, 5, 6]), - (1720634969.318238, [], [1, 2, 3, 4, 5, 6]), - (1720634971.383262, [], [1, 2, 3, 4, 5, 6]), - (1720634973.669218, [], [1, 2, 3, 4, 5, 6]), - (1720634975.727614, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720047138.987663, [], [1, 2, 3, 4, 5, 6]), - (1720239116.860589, [], [1, 2, 3, 4, 5, 6]), - (1720567216.089602, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720062114.160483, [], [1, 2, 3, 4, 5, 6])], - [(1719974901.32474, [], [1, 2, 3, 4, 5, 6]), (1720224712.94567, [], [1, 2, 3, 4, 5, 6])], - [ - (1719985511.407849, [], [1, 2, 3, 4, 5, 6]), - (1720140363.584567, [], [1, 2, 3, 4, 5, 6]), - (1720573348.34834, [], [1, 2, 3, 4, 5, 6]), - (1720649971.95392, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720325668.53657, [], [1, 2, 3, 4, 5, 6]), (1720407800.484026, [], [1, 2, 3, 4, 5, 6])], - [(1720313988.784401, [], [1, 2, 3, 4, 5, 6])], - [ - (1720137608.121513, [], [1, 2, 3, 4, 5, 6]), - (1720230219.916298, [], [1, 2, 3, 4, 5, 6]), - (1720576804.122481, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060264.40999, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982324.891431, [], [1, 2, 3, 4, 5, 6]), - (1719982326.95929, [], [1, 2, 3, 4, 5, 6]), - (1720072365.964045, [], [1, 2, 3, 4, 5, 6]), - (1720072368.013382, [], [1, 2, 3, 4, 5, 6]), - (1720185779.887725, [], [1, 2, 3, 4, 5, 6]), - (1720185782.013458, [], [1, 2, 3, 4, 5, 6]), - (1720230424.054008, [], [1, 2, 3, 4, 5, 6]), - (1720329463.631365, [], [1, 2, 3, 4, 5, 6]), - (1720329503.210461, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978020.337077, [], [1, 2, 3, 4, 5, 6]), (1720378278.012205, [], [1, 2, 3, 4, 5, 6])], - [ - (1720198700.302556, [], [1, 2, 3, 4, 5, 6]), - (1720417057.718199, [], [1, 2, 3, 4, 5, 6]), - (1720584860.786802, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720627126.675399, [], [1, 2, 3, 4, 5, 6])], - [(1720072022.286212, [], [1, 2, 3, 4, 5, 6]), (1720366423.980574, [], [1, 2, 3, 4, 5, 6])], - [(1720221042.039954, [], [1, 2, 3, 4, 5, 6])], - [ - (1720060635.731519, [], [1, 2, 3, 4, 5, 6]), - (1720210299.946067, [], [1, 2, 3, 4, 5, 6]), - (1720283154.070272, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720402469.930097, [], [1, 2, 3, 4, 5, 6])], - [ - (1719972611.185894, [], [1, 2, 3, 4, 5, 6]), - (1720227219.185837, [], [1, 2, 3, 4, 5, 6]), - (1720565623.051185, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060770.015072, [], [1, 2, 3, 4, 5, 6])], - [ - (1719979906.872722, [], [1, 2, 3, 4, 5, 6]), - (1719980094.376717, [], [1, 2, 3, 4, 5, 6]), - (1719980096.476308, [], [1, 2, 3, 4, 5, 6]), - (1720067152.682142, [], [1, 2, 3, 4, 5, 6]), - (1720067174.598435, [], [1, 2, 3, 4, 5, 6]), - (1720137635.975558, [], [1, 2, 3, 4, 5, 6]), - (1720137733.593423, [], [1, 2, 3, 4, 5, 6]), - (1720224539.774939, [], [1, 2, 3, 4, 5, 6]), - (1720323664.982932, [], [1, 2, 3, 4, 5, 6]), - (1720400336.830381, [], [1, 2, 3, 4, 5, 6]), - (1720400497.747426, [], [1, 2, 3, 4, 5, 6]), - (1720400499.843107, [], [1, 2, 3, 4, 5, 6]), - (1720486404.88152, [], [1, 2, 3, 4, 5, 6]), - (1720486460.387837, [], [1, 2, 3, 4, 5, 6]), - (1720486462.465262, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720494960.521565, [], [1, 2, 3, 4, 5, 6])], - [(1720492283.522426, [], [1, 2, 3, 4, 5, 6])], - [(1720588131.39025, [], [1, 2, 3, 4, 5, 6])], - [(1719965172.184078, [], [1, 2, 3, 4, 5, 6])], - [(1720313653.224728, [], [1, 2, 3, 4, 5, 6])], - [(1720133961.331413, [], [1, 2, 3, 4, 5, 6])], - [(1719969914.979558, [], [1, 2, 3, 4, 5, 6])], - [ - (1720051155.959984, [], [1, 2, 3, 4, 5, 6]), - (1720318569.685111, [], [1, 2, 3, 4, 5, 6]), - (1720499729.951734, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720328273.411971, [], [1, 2, 3, 4, 5, 6])], - [ - (1719982315.965122, [], [1, 2, 3, 4, 5, 6]), - (1720423276.150804, [], [1, 2, 3, 4, 5, 6]), - (1720586911.740203, [], [1, 2, 3, 4, 5, 6]), - ], - [(1719968679.211527, [], [1, 2, 3, 4, 5, 6])], - [(1720063388.278848, [], [1, 2, 3, 4, 5, 6]), (1720416336.796001, [], [1, 2, 3, 4, 5, 6])], - [(1720398479.735494, [], [1, 2, 3, 4, 5, 6]), (1720493260.033312, [], [1, 2, 3, 4, 5, 6])], - [ - (1720489609.661573, [], [1, 2, 3, 4, 5, 6]), - (1720489700.750791, [], [1, 2, 3, 4, 5, 6]), - (1720489717.546997, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720500732.208908, [], [1, 2, 3, 4, 5, 6])], - [ - (1720153118.225066, [], [1, 2, 3, 4, 5, 6]), - (1720314031.634943, [], [1, 2, 3, 4, 5, 6]), - (1720590337.724401, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720070140.554847, [], [1, 2, 3, 4, 5, 6]), (1720137932.433554, [], [1, 2, 3, 4, 5, 6])], - [(1719992154.926275, [], [1, 2, 3, 4, 5, 6]), (1720320574.945082, [], [1, 2, 3, 4, 5, 6])], - [(1719984916.520671, [], [1, 2, 3, 4, 5, 6]), (1720569849.178614, [], [1, 2, 3, 4, 5, 6])], - [(1720140614.641046, [], [1, 2, 3, 4, 5, 6]), (1720395184.350061, [], [1, 2, 3, 4, 5, 6])], - [(1720310387.035179, [], [1, 2, 3, 4, 5, 6]), (1720473940.199193, [], [1, 2, 3, 4, 5, 6])], - [(1720062920.051834, [], [1, 2, 3, 4, 5, 6]), (1720226181.474055, [], [1, 2, 3, 4, 5, 6])], - [(1720470329.222623, [], [1, 2, 3, 4, 5, 6])], - [(1720582334.499662, [], [1, 2, 3, 4, 5, 6])], - [(1720443828.896214, [], [1, 2, 3, 4, 5, 6]), (1720580682.756419, [], [1, 2, 3, 4, 5, 6])], - [ - (1720226425.344326, [], [1, 2, 3, 4, 5, 6]), - (1720310598.961662, [], [1, 2, 3, 4, 5, 6]), - (1720589761.631011, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720584698.862455, [], [1, 2, 3, 4, 5, 6])], - [(1720164879.185564, [], [1, 2, 3, 4, 5, 6]), (1720323846.480885, [], [1, 2, 3, 4, 5, 6])], - [(1720051096.071376, [], [1, 2, 3, 4, 5, 6]), (1720157299.452758, [], [1, 2, 3, 4, 5, 6])], - [ - (1720223524.412388, [], [1, 2, 3, 4, 5, 6]), - (1720326592.782923, [], [1, 2, 3, 4, 5, 6]), - (1720578100.065601, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720313647.455076, [], [1, 2, 3, 4, 5, 6]), (1720559337.211802, [], [1, 2, 3, 4, 5, 6])], - [ - (1719981335.449573, [], [1, 2, 3, 4, 5, 6]), - (1720067595.1521, [], [1, 2, 3, 4, 5, 6]), - (1720319132.823969, [], [1, 2, 3, 4, 5, 6]), - (1720491547.165147, [], [1, 2, 3, 4, 5, 6]), - ], + [(1720051532.484019, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720105713.331995, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720329565.847159, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720186008.567886, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326697.522923, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482974.426314, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720327526.250804, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720497558.23414, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719979738.339271, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720025384.961105, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504618.55439, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720136408.619257, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136458.666712, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136460.776795, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136463.761667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136465.813823, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153490.167176, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153611.687424, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153613.813758, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221238.819741, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221389.412602, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720234125.717526, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720245095.229565, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396821.910578, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502554.801179, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720237286.585886, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492842.0014, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720145259.463577, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720173037.951133, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720398629.834351, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720576515.470242, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720488634.248776, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719966672.507604, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720379305.230415, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485725.30467, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720056848.984567, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234634.97164, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326372.083307, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487169.130815, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719979630.05111, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720067082.599895, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720065455.678956, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720141594.235645, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720479638.868071, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720172558.775714, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589944.987293, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720240665.403432, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720403456.771406, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720151433.593775, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397705.729741, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407937.654196, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720063019.413544, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230670.007217, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572529.432945, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720062676.566511, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062768.411832, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062770.476807, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062771.394614, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156065.434007, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156180.339675, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720053274.311851, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574916.370766, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720403600.103166, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720070524.509752, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720330735.128105, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719980823.099161, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720109783.667678, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488536.75761, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720120539.020908, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235556.263511, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404531.8727, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720461710.602542, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720142147.27027, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720463509.177443, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720609249.094945, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720061653.09558, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331923.364924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493879.336969, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719981455.944035, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719981517.705732, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994503.81365, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994621.6397, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994623.698368, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994627.578717, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994629.663136, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994631.068061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719994633.142381, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720027463.767433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720027502.563106, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720027504.670674, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057341.723675, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057343.781939, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720145087.601179, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720145089.680587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243008.749524, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243068.439551, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318425.097956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318427.16319, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318432.221956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318434.329525, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418148.778433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418150.861104, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488202.399436, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488212.260625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488214.365566, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572393.815712, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720613041.916708, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720057097.342555, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317039.904735, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720483178.967836, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720181661.187285, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720199552.174104, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568803.062761, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720247391.136136, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410696.088339, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720599399.171422, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720312357.61565, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720052008.103911, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720400141.042944, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720210751.331903, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720503558.839248, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720241352.747626, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321677.766712, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720409706.122052, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720519728.980875, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719977467.931514, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568695.132969, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720071302.148667, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238096.092618, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720057437.769059, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720221473.506037, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720348129.55283, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482938.000889, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576755.035308, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720235902.362301, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720024782.723245, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720070158.75827, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720000651.858702, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720244645.395695, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411107.259775, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720191076.938109, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720322967.081356, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323158.146239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323172.234517, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323206.302768, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323313.146535, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323364.511129, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323458.282407, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720065260.493236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720065334.608797, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141650.234015, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141749.547675, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141751.641012, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154278.705276, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154280.760532, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229499.077048, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229572.436301, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720259010.216367, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720259234.335094, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720259236.42606, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318686.64822, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318843.45613, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318845.509738, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720363113.918907, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720363184.856665, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400947.604003, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400949.633637, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498232.720406, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498253.802808, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498255.908508, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586991.26782, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720587059.251675, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720587061.383312, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720638042.876812, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720638133.182092, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720638135.286491, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719978486.488845, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720406010.994165, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720062931.526777, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720142330.725196, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238332.287607, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404745.279674, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577388.350881, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719973721.653682, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720045556.714061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720286335.062706, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720408637.593505, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719980831.540691, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980890.3872, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980892.464391, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720027957.165729, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720027959.212697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055928.682589, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055930.747743, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138782.333308, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138842.547168, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138844.667335, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138846.225705, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153595.409537, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153694.792152, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222583.234486, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222651.732326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222653.840022, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231129.338916, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231262.508465, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315761.130281, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315844.746953, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315846.831435, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406873.849957, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406879.412626, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485467.197531, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485486.733099, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485488.847143, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485492.354688, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485494.434006, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581292.87898, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581372.990683, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719965396.997192, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720109840.37035, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720224849.338664, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311680.960628, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720593841.069028, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720193711.631887, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720355386.424798, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720137394.637585, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720227526.549035, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720601724.604091, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720242114.286726, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720495287.866943, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984060.976083, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233353.478142, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331822.027661, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499420.953642, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720327908.649598, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720327957.004146, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328002.921775, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328054.34555, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394578.210396, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394668.213374, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394670.323029, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410358.68385, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410430.047079, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410432.093006, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485479.982584, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485552.035405, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485554.099771, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576265.461408, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576267.553332, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580196.882833, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580198.938581, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580201.66793, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580203.765767, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720512918.56325, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720587573.354151, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720059581.380866, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226059.821101, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569936.860231, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720483812.243251, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720047890.599986, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720151933.610926, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720426395.237753, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589584.479646, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720050613.849179, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720183728.480776, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720245305.222942, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719974717.393306, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238913.058213, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720403863.202175, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720066616.245506, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720329802.077257, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720058023.220462, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720273250.296181, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720400521.741834, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720590006.799829, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719977522.311193, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394307.490994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720541599.758133, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720059720.64277, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720225557.277258, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318879.528985, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720448939.738279, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720159019.782951, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232688.231366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312031.934367, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720420263.292336, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720051467.327131, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226107.259649, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410027.350582, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719966308.30787, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136775.382126, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720453167.302523, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578911.142536, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719965705.478301, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720089492.274268, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720458943.365803, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588170.374851, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720137202.259506, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309242.730837, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720397209.557207, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720628958.303298, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719967303.936898, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720069496.922345, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719970996.586184, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720168525.715398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504098.515479, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720601826.09111, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719971199.057468, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068258.0151, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137337.044491, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719971421.175757, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720134959.956933, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719976305.13246, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720059646.658845, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720145964.773181, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233116.664838, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720436748.603567, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719969550.144929, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720315269.690666, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720274096.315691, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720274154.981534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720274184.028094, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720268306.026574, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720323182.163554, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720032173.053995, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720157155.365383, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314424.94755, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481047.114281, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720010572.095008, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968638.302149, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968762.98274, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968765.072701, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720005012.137582, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720005160.858454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720005162.913788, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720175681.69546, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720175774.033356, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720175776.151125, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720220252.732147, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720220252.777516, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720220256.747294, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492139.162569, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492141.256483, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719970987.569565, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720054508.915859, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720315224.08896, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720325854.156535, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720483854.080251, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720406510.418443, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720030600.544521, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720069524.719771, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484112.369653, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568851.121099, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720304785.385271, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720313035.494802, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313090.718424, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313239.783577, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313343.042083, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404935.491204, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404979.552845, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404981.647182, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501716.284759, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501761.154088, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501763.234903, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584650.853158, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584688.899508, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584691.020015, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720229088.205557, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720487228.612214, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720241088.456982, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720042764.160666, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984325.782697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720047953.098659, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720268267.887048, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720054622.362154, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134575.953204, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416355.096939, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500581.691615, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719972690.486054, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972877.103609, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972879.22778, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972881.797102, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972883.859612, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052338.317127, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052340.409592, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720069426.554888, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720069428.615973, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149027.365317, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149089.951754, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149092.012724, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234565.610403, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239125.82035, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239147.87241, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318243.573983, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318245.63705, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418009.877203, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418011.983148, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418014.464823, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485277.913378, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485280.026695, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574328.529507, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574330.633898, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581736.051228, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581766.135021, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581768.228326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652888.715284, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720328167.133332, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394291.998224, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720138278.025347, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720411684.615562, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719979551.790599, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062548.79153, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152645.092565, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720273648.542968, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720150050.836492, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720235665.517364, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720504709.666893, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720502409.011067, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652305.691241, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719983664.396995, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057964.860551, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720058069.016671, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720119055.986377, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720119177.882926, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720146988.862958, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720146990.940118, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720207091.824328, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720207147.984162, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720207150.045311, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221686.916464, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221731.792885, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221733.892091, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221736.114027, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221738.1731, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221740.137735, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221742.219472, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319188.083254, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319190.195166, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333160.336537, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333162.39224, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350382.882768, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350384.998862, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350385.400746, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350387.504804, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350390.868713, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350392.929211, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482928.905461, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482987.630373, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720549510.694147, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720549582.87966, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720549584.95341, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581476.586746, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581478.656771, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719977177.729628, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720393638.078415, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719980378.113974, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720443102.049493, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590770.939412, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719979883.308045, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230654.923495, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310908.910099, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719964829.898192, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719964832.003811, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985240.876339, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985242.911416, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985243.633507, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985245.665729, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060650.829248, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060759.718692, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060761.830242, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070260.443094, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070280.911994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070282.979246, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134645.425223, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134793.819981, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134795.932398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155938.192604, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155940.320279, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155945.041101, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155947.088061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236895.111761, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236912.473535, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236914.593968, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236917.655587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318871.824625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318935.358285, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318937.446561, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318940.05207, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318942.106239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405217.370251, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405312.528519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405314.627163, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413100.204244, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413102.291035, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496542.308228, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574260.260325, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574343.117651, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574345.20748, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578705.104516, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578717.159504, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578719.26077, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720071370.538676, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719972220.86175, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720227223.558904, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720047692.206123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720074479.043983, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221755.131247, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720343377.429715, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581159.65796, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720054906.379171, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326827.193456, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395837.565662, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719972411.855532, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972538.863121, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972540.935712, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063717.900878, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063719.954111, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070114.807467, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070235.024434, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070237.14674, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720097819.236115, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720097978.260021, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720097980.382821, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720151026.716063, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720151173.670938, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720151175.717239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720166439.941955, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720166583.693905, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720166585.791065, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720181553.630642, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720181555.746202, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242210.300006, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242331.451228, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720316730.127117, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720316751.481651, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350332.517593, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350427.724851, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350429.836812, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396153.382808, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396199.106453, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396201.15929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720424092.525755, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720424190.959176, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720424193.037739, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492456.877253, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492529.103048, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492531.198928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720583806.008143, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720583868.43082, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720648763.855471, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720648878.799852, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720648880.882297, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720071793.774403, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309002.505766, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720367384.379119, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719978345.677095, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720134660.416426, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720056400.339178, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137451.906538, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581731.115191, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719974999.631834, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720503857.499785, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720325249.830373, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719970175.486046, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061532.244847, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720387059.054565, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720157797.242967, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720490173.84352, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720568387.145132, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720027447.264569, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719979106.899872, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720417473.653713, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720153359.982848, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720468837.459019, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720047669.218866, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720230050.113895, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719975411.228945, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235199.496284, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720403154.17646, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720626578.282517, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719978136.275137, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720331670.572264, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719975669.597909, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719975763.25366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055306.937976, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055449.351479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067433.572041, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067452.84519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067454.935816, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233716.974937, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233884.056907, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233886.107033, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238869.144339, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239054.729577, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239056.811577, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720248048.594017, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720248147.506317, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720248149.540209, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323761.342714, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323763.381547, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400825.240853, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400844.815642, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410954.1329, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410956.230411, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410956.661655, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410958.800282, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414005.128157, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414035.742095, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414037.861356, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414039.522054, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414041.622559, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449836.553695, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449909.88067, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449912.006572, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504478.640048, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504584.183246, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504586.273448, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589586.941948, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589732.653657, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589734.757411, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589735.718174, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719987925.192586, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720319498.157106, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720140316.935341, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720581286.138288, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984942.453601, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720334036.972544, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568302.136228, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720231990.896895, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320392.727402, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720151072.246138, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309428.675922, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720652752.302257, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719977332.758786, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720135118.942837, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498977.766189, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720054300.10225, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720419250.119038, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720170242.586928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720322954.401713, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500416.057333, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719976447.157218, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720134454.623643, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720482790.529945, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720575291.374898, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720575147.912954, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719997197.65312, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137704.47896, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226085.527498, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720306837.86921, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720314781.298338, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720443503.319112, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719976515.23989, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720225806.720086, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720388901.256231, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720490185.842396, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720568142.650151, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720587602.828532, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720228569.783763, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720577136.698764, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720058398.793045, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317616.711315, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498994.241943, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719988512.009335, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411879.880695, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575546.218164, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720245099.046699, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652539.847041, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719965518.303227, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720241249.736668, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410560.906617, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566388.427971, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720033619.669265, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309514.690673, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584737.484501, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719981137.891986, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719981255.525287, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719981257.57542, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156254.934266, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156432.088183, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221245.352908, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221247.415618, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720306695.430622, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720306697.509606, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720399726.625066, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720399728.675873, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486842.405361, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486974.649877, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720494605.919949, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720494724.480053, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720494726.541559, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572824.284783, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572826.355789, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652512.753893, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652514.833743, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720044224.653908, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720583176.852571, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720567262.122889, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720518049.925836, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720148280.678113, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720391739.484219, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719983654.268169, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983761.844014, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983763.902973, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720014262.846562, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720014264.966534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720014268.064236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720014270.176366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062164.847608, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062166.93557, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070760.286042, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070793.879274, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070795.974998, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136175.682667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136177.782735, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150756.421019, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150758.537073, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226712.358545, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320316.371588, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396676.623722, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396759.330429, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482810.511366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482891.609285, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482893.739553, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502988.652815, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503034.447086, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503036.52898, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503036.606516, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503038.712119, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566567.148583, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566710.618717, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624425.022175, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624567.571474, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624569.66289, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652508.525789, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719978793.297818, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312690.624643, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720408103.17786, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720496665.901316, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720397084.267673, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720499411.209847, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720111853.777887, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720111923.412934, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139482.167685, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139533.842338, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139535.907287, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139540.267313, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139542.34773, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139547.051966, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139549.136732, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720464344.794745, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720464401.900918, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720464404.029255, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498850.875209, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499103.608103, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719973523.458065, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720233566.787523, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720407928.090004, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720032729.148346, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720062532.225999, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720034095.862663, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720491285.681862, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720096472.997597, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568056.766425, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720138718.911672, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720336998.597537, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489473.142035, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574315.596422, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720577328.151149, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720072713.69671, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720231002.690818, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719966317.997493, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238108.647106, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720146847.656681, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720239981.42926, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720081339.444776, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720234051.371763, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720236937.844197, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720501314.981075, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720495611.198831, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720071452.84595, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720320971.754361, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982790.224924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982861.078823, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982863.122702, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052453.241504, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052505.408448, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052507.485592, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720078456.868981, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137047.584706, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137124.096958, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137126.192241, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155528.420602, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155596.835697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155598.919376, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720204090.330488, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720204222.690243, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720204224.805824, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232760.467367, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232859.977733, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242903.930897, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242906.021355, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309697.411345, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309699.483954, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406346.354509, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406523.466919, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406525.535072, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720065979.154591, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720325699.423285, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720244750.093352, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394343.192185, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720193298.590097, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720315677.193089, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720501281.07252, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720055721.622214, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720137839.895581, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231251.548774, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720350224.693877, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720519304.741337, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586487.784295, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719969181.053709, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720434586.266895, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720070912.148493, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720244703.673132, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720494833.034907, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720053732.993216, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053735.086697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720081490.114819, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720081492.188923, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720108329.744396, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720108420.858541, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720108422.93886, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142971.786605, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143021.896153, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149975.921352, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150041.125351, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150043.15518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720200733.408027, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720200744.366236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720200746.48024, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226248.428928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226387.261389, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325189.273212, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720367266.448359, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720367268.528501, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397514.119584, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397583.541623, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397585.62972, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407649.068004, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407859.450723, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407861.5267, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418226.184583, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418312.907521, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418312.959891, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418314.508588, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720429033.410454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720429217.5183, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720429219.58254, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720476196.299215, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720476290.414317, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720476292.497993, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496668.635514, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496670.762669, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566807.578929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566881.524889, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566883.613068, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575742.398153, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575760.407369, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575762.530879, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720623060.799492, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720623163.775703, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720623165.819144, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720490829.088908, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720222040.449568, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328183.580613, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581997.108309, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720631726.024509, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719969186.42388, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236467.453142, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720460294.599805, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720328624.599959, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411036.02508, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720470233.314202, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719966062.758672, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057471.705526, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325034.717518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407309.902625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573477.911506, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720063887.70449, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720343326.152899, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720411362.644921, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720395606.751317, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720155980.858558, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720450339.669296, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719981567.460091, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720587320.169523, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720245122.915738, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719970229.063219, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720488361.805483, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720320009.047059, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720139484.708505, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720396780.73649, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720238094.386701, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720627574.598265, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720136834.089355, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720396824.609765, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720225652.369657, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982133.012616, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982177.631804, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982179.720602, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720006591.274361, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720006644.930183, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720006647.03435, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720460548.964008, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720460614.237345, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720460616.332418, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585282.645498, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585293.462072, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720370572.550118, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719973160.879923, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720329101.982409, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581501.430356, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720063998.039445, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232764.384684, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502473.633051, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720153647.635598, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720225923.85076, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413430.570698, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584131.042756, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719966759.043742, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720405936.570297, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720144919.519677, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720402676.1685, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720402994.034134, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720497341.728864, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719973785.927392, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142506.754009, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312482.395361, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578049.42885, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720143203.796648, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720504600.034248, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720138317.024564, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720307922.860078, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720576710.045341, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720237948.24219, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720322691.233406, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412663.957815, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720342019.617667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720342090.227667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720342263.731169, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720342307.569989, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720342413.538738, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720342570.868506, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720342664.423143, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720053725.982337, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137089.95596, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720250340.159455, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720408080.82431, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720502215.54816, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720051018.757074, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720221304.68857, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720055639.220711, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242136.136068, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501308.452889, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720210019.832882, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720222496.41532, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720221892.596089, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720488555.303827, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720055240.779901, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485059.84637, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720520102.630634, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720591031.4354, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720570592.888394, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720059956.606064, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232781.82764, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489307.963369, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720466563.789269, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720120332.505828, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720501386.247192, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720045443.968104, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720337612.000658, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484793.823359, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720240516.409323, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720508486.303913, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720056682.445295, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239570.480365, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720399243.691516, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720065346.577694, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720111179.563476, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152182.18393, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720456368.150945, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720037842.027886, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720051512.155726, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720316085.436368, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720153922.872643, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720316484.292604, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481626.562697, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720304528.044157, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720587171.914424, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719969690.052003, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720098093.259497, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589467.401983, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720182994.851728, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720490206.204252, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720305269.133214, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720580679.401674, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720582113.001824, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719971867.373391, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719971869.452767, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983561.418747, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983615.306689, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983617.371374, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983622.154397, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719983624.239597, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057585.854293, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720127843.991043, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720127952.545227, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150451.197164, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150472.889245, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229579.372015, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229585.29839, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229587.33746, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720272362.151724, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720272395.494166, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720272397.584197, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325287.360716, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325289.430457, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720392144.674955, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720392146.786158, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406690.885685, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406692.950513, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486441.134231, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486443.192435, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720648828.296221, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720648830.340132, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719977053.236432, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720146886.388756, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720147721.983335, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720577319.095652, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720187232.833461, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720309745.334443, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720525020.981442, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719985270.896874, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720147203.361104, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719975189.590595, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720153681.561666, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315141.854012, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720483759.06017, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720632532.362134, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719969377.021113, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719969547.865829, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720050670.589639, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720050713.412665, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139076.150907, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139087.933212, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139090.022598, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139092.090332, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148904.698605, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720197454.202625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720197456.301898, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221957.937687, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222151.210074, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222153.281944, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231319.785278, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314287.823226, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314375.707773, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314377.787834, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331369.745063, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331582.949466, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331585.058912, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720399235.526545, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720399237.6268, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410762.341061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410808.990309, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410811.040448, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493330.828194, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493516.887173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501442.580123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501548.316894, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501550.379738, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573012.279738, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573204.24471, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573206.359087, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573210.996145, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573213.096745, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719984464.146305, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719969484.575186, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719967098.321792, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720140304.171738, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720067679.407113, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720240007.297001, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499615.946055, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719984745.989291, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720088802.060799, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226330.102201, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720057325.702019, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720499465.567145, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720055478.668518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055619.422527, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138025.392906, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138074.32289, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232045.90559, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232073.337701, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278094.793407, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278096.912409, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278099.569789, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278101.660519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720324663.973123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720324666.034118, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412864.0991, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412932.896312, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412934.95735, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493768.204791, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493848.668367, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493850.800293, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493853.855696, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578407.565863, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578455.012928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578457.12311, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720592507.954368, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720592695.674207, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720592697.763035, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720448820.538088, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720448848.354821, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720448968.980221, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449109.647373, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449132.605916, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449141.226924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720449174.132961, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720143295.563285, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720009875.184202, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720064301.403426, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221459.433168, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720316122.630709, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720625396.811387, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720064525.079458, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720600790.059805, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720053513.239524, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720533559.490134, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720222657.803241, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719971419.792625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239049.653382, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497253.487835, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571009.60795, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719978213.57048, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719978402.543586, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067921.564313, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068031.2973, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068033.364045, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720076693.193638, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720076695.234922, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720088372.082518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720088448.747115, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222636.476764, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222701.214913, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311136.481341, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311279.356667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311281.435353, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321937.516249, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321977.750869, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321979.826956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321983.309368, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417820.177018, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417888.907443, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482544.485269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482650.874077, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571012.586842, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571014.653099, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720067135.000485, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226886.323383, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720626810.190995, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720021468.494681, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720244311.296556, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720054497.052088, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315797.04068, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396623.976121, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719970439.050635, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720411294.606462, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720047660.240807, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720209425.126479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417042.301423, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720579466.836909, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720068666.058135, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720224717.712974, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313644.184984, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417247.572309, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720217112.012918, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720228893.793094, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719965114.583168, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221700.128257, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720359492.65181, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720149938.452021, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150083.518978, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150100.711862, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720403516.136956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720403602.399166, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720403688.061721, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720016151.530651, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720126052.51206, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243360.967974, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567481.805169, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720259903.388453, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720495071.607118, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719978731.351246, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142275.008236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720225627.748133, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720599835.060544, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720308817.017884, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720500376.721695, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720062080.162523, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720424051.051867, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577193.657241, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720226358.301934, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720611516.599998, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720142831.087971, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568727.59182, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720045127.801767, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720598254.557545, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720230498.737196, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720502519.921733, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720149819.132452, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720317818.669453, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719965630.184525, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720566194.006106, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719996710.23806, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720053587.04154, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720476400.319672, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720238998.499612, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720049964.339669, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720503256.459045, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720629914.75266, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720067406.552276, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720192823.078475, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720615636.068682, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720050726.320669, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720159164.117987, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720583837.972687, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720470505.483407, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589293.330858, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719990309.924021, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242385.881249, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720648573.041044, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720059240.88106, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720486550.385795, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720232277.114726, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720156360.413945, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720415380.907597, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720143721.130937, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720093040.94431, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720230385.831757, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720313919.101562, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720600894.542752, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720008883.059792, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720151981.800615, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720583883.771582, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720054595.476172, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720494101.96425, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719975987.869421, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072012.445937, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141541.892965, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719974700.775073, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719974810.784479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720022010.687673, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720022125.15125, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720022127.183082, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720022127.850327, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720022129.972437, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149346.519881, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149423.39517, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232515.945385, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232642.031851, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232644.151326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232649.102724, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232651.213687, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720291284.378849, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720291307.651917, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317724.65539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317962.176994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317962.221761, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317967.870483, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416284.403485, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416286.45094, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720446964.44037, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720447111.491786, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720447113.551591, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500857.609857, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500933.241251, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500935.342693, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720550391.631024, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720550393.677097, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571962.115275, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571964.156322, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720300973.659698, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720502088.420309, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720226060.114355, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720367668.242413, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580879.469873, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720148122.993839, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720283848.988921, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720392902.670008, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720547569.939146, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720164561.277691, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720322322.293618, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720394391.029382, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720578227.91725, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720427348.104988, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720586312.438776, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719967279.972433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719967282.055508, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719986090.097845, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719986173.00659, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719986175.082864, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720034526.875582, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061201.725715, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061294.240057, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061296.35589, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155141.396653, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155143.510508, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155145.301155, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155147.393972, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231098.024705, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231317.54759, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720231319.611985, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720271983.621164, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720271985.710974, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720316981.40392, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317019.941522, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317022.040965, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411936.226228, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411963.208146, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720479757.589657, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720479839.302922, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720582109.835415, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720582111.914294, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652093.707438, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652211.598303, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720579951.356488, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720593973.655643, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720061475.003195, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720270392.101123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415797.057544, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574029.592383, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719987865.032004, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720212776.214811, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720315089.869542, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720578088.622431, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720575422.335555, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720329438.482756, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720443842.432414, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720135846.308239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221161.535587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326226.738859, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719977789.721113, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719977899.031956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719977901.119465, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982587.985388, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982666.211377, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982668.29279, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982672.56956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063592.708606, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063594.776009, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720145103.906614, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720145165.665926, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720157026.459569, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223512.011646, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223586.453989, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223588.535794, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720329405.565358, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720398313.307695, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720398429.724071, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414381.775047, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720446240.471098, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481889.793923, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481891.93036, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489136.015971, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489247.728734, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720318482.752639, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720242162.48487, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503535.294123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590538.582039, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720148407.104121, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720154168.367205, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568213.544423, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720069001.717509, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720346135.538471, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489854.284499, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719967260.706099, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720082538.484733, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720240732.567635, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395713.187024, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719968640.279026, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720058387.048155, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720240163.514327, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720391336.792179, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720310285.653948, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589147.207321, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719973140.021275, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720504055.006021, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720115792.85023, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720140689.444004, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312169.980048, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720399894.527727, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720316227.642169, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720484121.740556, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720150629.632571, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312593.72112, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584121.246833, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719966806.196729, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492831.262792, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720069584.25825, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233172.76065, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317363.164219, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720227600.733956, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227600.784387, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227605.27419, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720269710.791405, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720269759.332462, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326344.424672, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720369614.287387, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720369719.27491, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720369719.331218, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720369721.899004, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720385493.685201, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720385551.219825, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720385553.316418, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720450115.39061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720450117.502598, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720450118.78177, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719969800.978378, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222415.35262, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720434706.74629, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720237451.24597, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720585495.150654, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719970937.04025, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719983075.420902, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313367.078665, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413122.113225, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720155749.238687, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720491353.243799, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720060021.000595, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719988378.536367, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720228662.183092, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719981886.782157, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720156878.496962, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720582313.689559, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720232302.477057, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720493756.958556, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720295778.241704, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720021503.203052, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720325452.491454, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720527219.478404, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567646.306507, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720223792.29193, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720006636.772706, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720006795.60427, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720006845.799981, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720007022.741945, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720007095.581047, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720007134.850115, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720025117.762503, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720025308.512649, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720025310.568037, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052547.163003, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052600.03312, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068046.902248, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068213.189912, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720144711.311281, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720144713.407177, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222638.332245, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222640.418838, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242141.813366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242245.921587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242248.011768, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333146.03005, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333287.562561, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333289.592652, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333292.319879, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720333294.386109, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396984.211837, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397094.401782, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486134.144443, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486136.211044, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486140.873481, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486142.970428, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497754.706526, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497979.155047, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720531991.462042, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720532199.030662, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588796.771517, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588842.077879, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588844.116306, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720239926.764196, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720395045.1902, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720431147.297621, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720240748.713179, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719972432.742571, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720410198.607466, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720566548.549011, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720455428.865155, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720498325.755933, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719983684.033908, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319741.991515, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414800.645761, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484979.12583, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720134283.600008, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720409485.01654, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719981074.661088, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143880.41593, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229983.175788, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720060903.203334, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968419.743912, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968490.438903, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968620.857174, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498112.351156, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498358.36836, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498468.250047, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574778.111823, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574806.5479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574917.425735, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574933.603291, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575020.164914, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720406407.483318, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720412099.352018, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720498223.084881, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719979024.598321, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720114791.984992, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720241390.157269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500283.345509, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720569522.382331, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720146840.111051, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720287268.372643, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720583508.926048, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720229146.528014, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229340.131801, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229424.480475, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229565.859999, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229567.783491, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229693.297904, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720229755.453165, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720098291.146186, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719983104.788269, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720070626.816099, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720226820.995006, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720316639.892049, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589368.875624, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720070877.576019, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720234703.959519, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719978870.060134, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137971.413991, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491059.303159, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719995043.481796, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720148819.805573, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720052005.359573, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052127.565063, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052129.679258, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720064915.795875, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720064917.840723, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720064919.250429, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720140563.359858, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720140686.221967, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147133.126896, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154606.237768, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720208312.107821, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720208397.77235, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720208399.88578, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226692.740751, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226809.874422, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226811.929607, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320735.680282, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320737.781583, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394544.101953, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394546.228449, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411628.159882, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411765.678009, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411765.737071, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411771.063593, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493021.815332, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493023.89141, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720547092.818141, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720547133.337079, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566405.934125, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566407.979963, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720592934.864349, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720407281.391395, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720578489.911262, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720393905.799101, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719965431.440319, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719965547.770505, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719965549.880668, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720010279.644796, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720010481.117481, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060297.061777, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060299.106745, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072795.790373, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072933.175213, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138923.382269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138952.892452, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138954.952138, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243737.055635, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243742.725476, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243744.812736, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278868.092914, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278981.120539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720278983.221413, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312851.319112, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312961.59678, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312963.701002, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401167.589016, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401192.232905, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488671.153932, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488673.262556, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498148.914747, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498151.01221, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585902.00157, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585904.068243, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720627230.183177, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720627251.343451, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720627253.395817, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720049050.269443, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720406587.77676, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720201120.604139, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237348.670203, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503188.882528, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720137961.069782, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720233994.333193, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720148673.115174, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720017472.013793, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238395.438066, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481118.520931, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624077.141735, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720460985.277631, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720065960.10824, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568092.250721, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719964803.220143, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720072690.78503, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719973118.028284, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720148963.270876, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720055800.056897, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147428.656208, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237025.123131, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326902.440989, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719967443.988967, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719967507.96168, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719967510.01003, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719967510.547419, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719967512.630086, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138300.130825, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138300.228601, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138302.137449, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720266243.760636, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720266262.29505, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720266262.382243, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720266267.714044, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720376066.44502, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720376075.005446, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720376075.055395, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720376078.271297, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720495615.317205, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720495625.121167, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720495627.190587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720495631.668389, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720094115.933922, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720327035.126978, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652576.382878, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720494001.577927, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720102356.301353, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720244955.2084, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393949.41044, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576986.579566, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720033048.609785, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720402968.773862, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720230211.716966, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720059787.289306, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397378.208597, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481196.422422, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720003149.057462, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720003372.883061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720003374.955179, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720039541.861276, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720039688.427965, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720039690.485555, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720048625.116329, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720048725.117697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141659.610639, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141661.665952, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720196426.042225, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720196487.09087, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720196489.183893, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720207066.952798, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720207237.857105, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720207239.919375, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720271033.503072, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720271035.587795, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720583123.471438, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720583125.576798, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720154856.626343, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226072.346309, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310601.449016, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720242303.35601, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720078404.748142, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720147584.809447, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720178488.289574, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720306985.894457, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720146748.830901, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720406666.368212, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720023013.684634, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720091577.184398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415121.299085, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720056649.932043, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720323285.584787, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415154.592994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720437978.9498, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720473849.744602, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719984649.0919, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984690.14033, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720049900.611104, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720049902.719326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070202.827545, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070219.8164, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070221.892056, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137406.074377, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137495.69452, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137497.797134, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328661.139393, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328739.939669, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498901.295947, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570987.624349, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720602646.235039, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720602812.376711, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720602814.446349, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719974528.289353, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395723.591687, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720617442.004095, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719975592.337919, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720057591.780745, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720488152.255523, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720148926.955422, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232410.538746, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720408447.752538, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720242892.942203, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720322823.10199, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720400088.852099, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652752.741385, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720412428.936544, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574790.414977, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720069130.346249, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720157382.402748, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720157476.064866, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720157570.728611, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720157662.381552, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720168580.805279, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720168760.793692, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230288.646191, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230430.103977, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243393.667459, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311604.919662, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311771.258364, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311773.310317, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720324823.664232, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720324825.721978, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393374.344255, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410680.226051, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410682.252163, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498394.961086, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498440.73496, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569716.948564, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569812.275586, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569814.333894, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569814.53133, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719978988.407662, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719978990.511958, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984066.593696, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984323.803693, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984325.863773, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152078.595081, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720225565.930941, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720280378.036955, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326955.218979, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326957.292481, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331017.031137, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720331019.121504, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410756.685202, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410758.796614, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417802.859919, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417804.989442, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487313.059882, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487498.533155, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487500.652063, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487503.708405, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487505.805861, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501546.266299, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501655.51812, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575741.153236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575891.79104, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589520.786652, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589642.390304, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589644.452771, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720615233.591986, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720615337.890481, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719971542.018584, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719971788.12398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720117268.913487, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720117270.991206, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143198.612101, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143429.084839, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238625.308642, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238757.81922, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238759.894117, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330550.917977, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330626.459228, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720378937.313156, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720379038.375789, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720386358.224787, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720386360.275601, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416486.117358, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416608.109114, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493716.833205, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493844.641363, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493846.67691, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568118.486107, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568219.230995, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568221.334344, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574746.351324, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574815.297689, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720233195.120615, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393731.964556, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570257.699261, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720149655.238203, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720352361.227124, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578697.147852, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720411277.985506, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720572981.673421, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720569584.93865, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720311303.894177, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720576463.87807, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982989.782732, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720080708.007665, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234553.333259, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719983711.203136, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720395076.590109, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968905.802345, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720054751.228152, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393228.571573, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720151965.57438, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720265917.280767, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414597.498797, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569352.211054, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720139623.448558, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720413909.371495, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720332156.972433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486770.808084, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570506.129092, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720046377.309817, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720144405.103977, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720311749.460887, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720480404.801297, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719965504.779832, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720489219.425884, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720480774.306063, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719968486.759348, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720229505.650825, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720122526.844622, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720142320.524851, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720320995.267452, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984296.990609, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984350.22369, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984352.257572, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052997.807277, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053049.304507, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053051.378602, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150389.546489, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150391.660121, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720168392.833864, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720168394.931787, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720218901.13549, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720218984.364651, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720218986.444335, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236871.413173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236873.52, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318899.245869, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319077.080816, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319079.181328, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720421585.966107, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720421692.177002, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720421694.269891, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484559.101295, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484634.686657, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484636.791229, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484640.876498, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484642.914839, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568978.955929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569083.551067, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603472.634189, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603622.57534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603624.69381, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720204831.715905, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719985836.773241, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720227063.151216, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720226998.434162, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720413326.470543, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720484747.542658, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719975290.47648, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719975421.539502, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719975423.609947, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719975424.130571, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719975426.224942, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720024823.782769, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720024943.32157, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720024945.350078, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720024945.905366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056619.663053, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056822.318399, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056824.36183, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072281.168332, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072283.222603, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134154.949613, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134376.323715, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134378.416906, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720140112.874786, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720140131.322854, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720140133.38169, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238635.597737, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238637.672121, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418306.625113, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418333.5673, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487528.439985, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487546.337876, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487548.449392, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502509.125496, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502624.411704, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585053.028856, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585055.08891, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719982052.592392, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982258.203523, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985183.079021, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985305.780432, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055777.47168, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071284.174477, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152558.44266, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152671.333552, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152673.415669, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720182134.94743, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720182137.028427, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720182138.842693, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720182140.958073, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227575.333539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227736.260264, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227738.300477, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236068.538351, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236070.60483, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317757.071545, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317866.130343, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317868.22788, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330462.980036, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330707.655663, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330709.750072, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720373940.747523, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720374027.697475, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720374029.799405, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406670.90306, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406844.478936, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406846.592556, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406851.281701, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412576.66958, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412652.412012, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412654.533239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486184.910769, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571066.49819, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720626129.788949, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720626261.332132, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720626263.446226, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720626267.27108, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719972691.157799, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972822.458675, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719972824.589752, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719993329.829737, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053155.834123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053293.330528, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720084358.281667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720084522.554824, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720084524.658959, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153146.842639, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153159.620793, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223041.359927, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223107.178767, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223109.301943, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243608.145196, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243715.813915, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310055.295457, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310225.190394, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310227.250668, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720374255.295948, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720374257.390432, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397033.790744, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397192.93351, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489562.012912, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489620.124167, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489622.2461, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577615.944083, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720595908.263871, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720596022.795818, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720596024.909409, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720596025.112291, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720596027.181848, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720410184.878056, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720446097.457008, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720582142.651169, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720496385.651227, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588018.159792, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719975737.968693, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720069758.403541, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720573220.196789, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720435170.4772, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720156838.062846, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588244.606338, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720072706.921977, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588899.722119, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720058343.607628, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720314365.315505, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720502417.751936, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720302708.367359, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720585704.559633, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984540.656777, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720146973.8651, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720341798.159409, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482149.273983, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570969.604085, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720311167.154928, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720404884.472902, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720481370.176729, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720098969.778426, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720542708.023885, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720149583.597081, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314574.406545, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416038.659142, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572347.697131, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720033450.660601, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720033450.752555, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720033455.770905, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400227.89913, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400250.299243, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400252.394995, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417432.186774, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417504.33498, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417506.39095, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417509.515927, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417511.647347, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417512.311827, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720512787.544525, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720512787.637452, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720512790.509437, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720546384.085434, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720546402.635026, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720546404.721606, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720091612.414745, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394180.692823, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720499565.692616, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720050050.500015, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720050118.092842, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720050225.108458, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720065727.65261, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720065830.735126, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720065888.617825, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720065986.346168, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066099.675624, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066274.481661, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066349.195281, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720151340.048882, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314849.375028, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413869.9313, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720054419.118301, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720399142.008777, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720070403.925696, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720244978.0606, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588083.280232, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720142944.669634, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317829.682224, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720402172.873968, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720135813.27587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720344219.879026, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720587780.127476, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720307062.497702, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720145491.250495, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720586242.178403, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720586566.015615, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720409077.369118, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720569722.833936, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720098442.029928, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720391796.053942, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720243240.863801, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492060.909226, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719967064.859664, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720055971.205432, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056017.075129, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720069354.406111, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720069356.466395, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153990.829373, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154034.130574, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232518.365492, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232668.084829, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720232670.147567, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720247796.598987, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310742.132713, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310784.012123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320091.334971, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720357505.367765, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720357507.406388, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404625.988586, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404726.50447, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404728.609789, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417440.696768, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720460381.831877, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720460489.831088, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492881.459734, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492883.570789, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580680.591028, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719975556.382414, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720231475.932226, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720569569.754826, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720043952.413223, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720225500.222696, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719967819.052883, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234292.697748, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397113.348799, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720087477.672876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720438489.760021, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720577383.739689, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720047896.111507, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720200244.93862, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720464543.942733, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719970307.394382, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719982131.954439, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238111.874625, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719966189.201726, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720150700.452652, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720142072.057736, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720063956.632264, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720057020.243682, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719973656.343743, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719973767.615562, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719973769.702368, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720050422.073716, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060932.515015, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061076.268193, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061078.375626, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061082.695369, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061084.803345, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061088.695247, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061090.795592, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720135057.814031, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720135295.655111, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720135297.734383, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156608.706907, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156610.771323, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720208160.885537, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720208274.821579, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720208276.929569, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223270.224257, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223272.316827, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223275.15326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720261350.082829, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720261423.329391, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720261425.427693, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319448.712298, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319512.283877, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319514.384024, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397163.860459, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397201.824506, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397203.898302, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487465.098454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487616.241062, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576783.799559, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576837.625767, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576839.747181, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720621584.709553, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720621686.14789, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720210871.32264, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720324564.785043, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719976074.774068, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720432422.057214, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498059.505822, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720537307.322626, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720051279.943281, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720326635.291429, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720317156.788498, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720409687.362687, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499324.086042, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720058380.956986, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720150021.258812, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720053489.906165, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139673.741326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720257769.454421, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393246.483443, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653126.121555, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719980029.84453, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720579706.660021, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720044200.360238, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720081853.12837, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720052881.805602, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720072654.6007, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238922.414211, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410048.118631, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720307869.769519, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720016591.216479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720157097.134758, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720238731.063819, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575486.387284, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719965711.424761, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719965713.531779, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720049361.440421, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720049363.495467, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070584.34326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070586.439897, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070588.168108, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154076.359366, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154271.555582, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221139.621509, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221264.378154, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221266.479342, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239415.452192, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239475.014596, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239477.07742, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313035.217622, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313041.373706, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313043.420222, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406631.8599, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406659.023715, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484615.165994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484638.913162, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497880.450011, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497934.842426, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497936.912581, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720540604.563371, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720540779.42356, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720540781.553641, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570083.468668, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570174.103962, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570176.16906, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720583667.401678, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719984388.470208, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057777.644161, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057953.012529, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057955.119335, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148795.685708, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148805.802813, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148807.834184, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234649.035149, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234705.911474, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321956.32096, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321958.41442, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720409662.220157, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720409664.333692, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720447795.315077, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720447797.391813, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720483016.135213, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720483018.21033, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720483019.948558, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573042.040836, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573166.473551, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624631.359534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624673.478312, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720072684.014623, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308176.896274, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404626.250723, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719970599.437881, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066959.831691, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067155.392921, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067157.488109, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155932.952678, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156052.447154, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156054.565087, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720176991.157569, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720177007.156433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720197632.204363, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720197634.246364, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720245139.96838, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720245142.060531, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313085.938317, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313087.991269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720382887.239454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720383102.784337, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720383104.858248, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401645.882852, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401875.751914, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401877.871081, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401879.349072, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401881.439362, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414595.608826, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414633.289105, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414635.359202, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417003.580682, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417074.130853, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417076.197409, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480715.553431, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480828.705337, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480830.783164, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720579482.271054, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720579503.249382, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720579505.309044, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720320578.9281, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320637.501704, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320671.3461, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320700.900689, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326925.640353, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326927.740401, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397880.433215, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397991.949085, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407395.883774, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720478571.564518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720478573.689929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496055.710657, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496250.423433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496252.533919, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567595.861171, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567634.8402, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567636.90682, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652785.237133, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652836.758383, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652838.851539, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720076323.446198, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720076387.202961, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720076463.503404, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235511.111341, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235587.152102, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235604.104726, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235788.441489, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235897.829327, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235943.361057, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236088.122922, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719969865.146509, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720088372.900286, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720220494.799398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488909.409034, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720063420.61895, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320803.577679, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401999.385093, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720051291.94966, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720313692.587964, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720509709.170957, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652928.475583, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719976500.586248, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720063184.061031, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720147998.634564, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720575037.093899, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720594897.858543, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720238660.290085, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720306835.46462, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720401110.356341, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719970976.422012, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720051629.137902, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720301759.327348, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720646663.705407, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720077214.628033, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720579842.451312, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720403179.578891, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720573175.772465, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720418161.36421, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418260.71249, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418315.726571, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418380.031953, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491482.634884, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491528.332034, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491530.434212, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573999.084897, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574047.543743, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574049.630747, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720616534.181229, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720616536.227681, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719971505.975792, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309386.016213, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570539.167487, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720026981.201845, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063393.228975, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569870.489752, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720151334.562097, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311454.894847, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720483363.072169, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720051176.858561, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567049.0934, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720300278.98565, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397622.151994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487075.583534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572927.092976, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720588311.663694, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720323338.447054, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720499740.21156, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720239215.924016, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720407168.197067, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720496803.3956, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720578053.220463, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720400566.962842, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652817.676145, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720234566.739671, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720335553.524142, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576366.993741, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720058095.694475, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720499846.305083, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720069736.856188, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720327054.018462, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720446989.50202, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720579246.321269, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720065515.046196, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237193.252454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720402549.014306, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719965737.195869, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057334.427369, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221205.840325, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720366343.985963, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720195598.557753, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719980678.939359, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720144995.169791, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720583721.214132, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720054537.756175, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720182546.976397, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415420.418491, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491014.558376, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568712.840731, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720061881.320656, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720352102.705661, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405007.368123, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720578542.112522, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652582.644175, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720243826.422296, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719980177.888359, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720151191.015847, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578744.147878, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720401711.559261, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720166076.219132, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603429.438791, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653029.910009, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720060428.267185, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720330543.204866, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720023596.681592, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492712.578171, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719969468.250895, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719969673.12603, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984075.563213, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984158.542506, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984160.639094, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719984161.840978, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063496.706949, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063498.73801, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071811.706281, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071892.339384, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071894.401443, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141092.670014, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141281.129314, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141283.221705, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242813.561025, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242887.120065, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720242889.197122, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314744.527265, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314759.642908, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314761.711826, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720371097.307425, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720371255.548011, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720387058.372995, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720387060.502073, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404975.528018, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405017.654969, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405019.759385, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415081.995346, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415260.662438, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415262.742795, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485117.023333, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485119.095263, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499098.798714, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499235.930954, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499238.042676, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569739.038396, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569853.204944, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569855.2363, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720602936.713875, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720242969.422529, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719964838.834772, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720091821.44426, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233192.310563, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328141.79034, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496224.014897, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720152285.903631, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243334.372125, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720379463.678962, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720542353.379097, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720649368.688756, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720226523.433881, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226623.918185, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226651.194519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226742.683406, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330187.550014, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330210.231169, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410272.539479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410274.655647, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480303.2625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480415.671856, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480417.738288, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504693.498524, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504764.21831, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720504766.268173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568377.567722, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568452.706691, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568454.778127, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720150751.139246, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720064945.077586, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720176851.77124, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413751.53369, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720067667.982332, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498323.491767, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720640332.912224, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720586416.962046, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720403065.106609, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720468529.097883, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719976409.626599, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720617974.74258, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720155789.338418, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719965523.519862, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720492317.02938, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719971602.527103, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720069918.036547, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149900.77775, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720143447.493022, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720292005.708479, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720316731.010367, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720061643.180585, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719998587.453659, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141642.077196, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308402.56405, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416584.28358, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720587211.681421, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720155992.271335, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720572458.818891, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720052898.053761, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720221610.587492, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312064.403238, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720147178.948005, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315892.264762, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484335.142158, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720625426.867126, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720225964.225383, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720486617.901554, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720064206.744859, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720148855.512919, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719978022.859036, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720225065.814898, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720379679.901663, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486481.106043, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720072107.565425, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720244247.598994, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720418305.8177, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719982059.871483, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719978817.113542, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720138229.977179, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720069967.627991, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720327850.533176, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720047008.96098, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720399885.70332, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720241326.183043, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719974240.573502, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719974319.570753, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719974321.645618, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720023281.111928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720023484.341612, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720023486.442918, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056803.840688, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056805.906524, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056810.106719, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056812.20004, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070833.346034, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070835.405627, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070839.751918, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070841.8631, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143274.991396, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143497.358536, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720205396.067954, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720205567.621928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235968.291387, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236089.012578, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236091.096483, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720299309.484376, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720299348.029909, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720299350.111093, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320587.866423, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320589.944508, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400218.389368, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400220.487059, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492976.763916, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493019.503907, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493021.579652, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720122662.758187, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720005466.226878, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720152200.991189, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720481835.844194, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580183.828864, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720070662.89957, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720142183.650314, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720411252.551579, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720072507.675137, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238913.204492, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720218011.114445, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720302385.101079, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720570186.762002, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720157661.668233, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720002096.475822, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720002098.548489, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066947.715378, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066949.844651, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720105199.7729, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720105370.978068, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720105373.072451, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134686.761223, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134688.87969, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154938.58341, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720219977.007902, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720219979.064108, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720250673.20197, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720250796.014257, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313894.440119, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313896.495204, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313896.774105, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396853.1643, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396855.257174, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489852.456446, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489986.86769, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569682.852233, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569767.225411, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569769.334261, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581192.763754, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581262.544992, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581264.629216, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581266.203535, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720226441.129883, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226519.948161, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226639.444269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226731.198095, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226779.385516, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226788.674966, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226923.560385, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720487951.436457, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720038002.665527, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488750.698306, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589885.270178, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720580260.501907, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720237662.32438, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309542.106408, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720573441.412558, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720598006.382998, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720249262.676111, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968867.096755, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406515.635103, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568473.896114, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720063183.618875, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720313109.473272, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720418083.174351, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720106024.609, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720058454.321955, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720062639.625591, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720221670.858026, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496857.495022, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719974856.395033, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053608.017225, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053669.477447, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053671.560518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062649.578553, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062651.66265, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062653.377042, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062655.44862, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720082692.43711, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720082771.847834, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153671.808662, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153713.489374, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153715.599402, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153716.387598, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153718.446591, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239246.152588, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239248.241024, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239250.77294, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309956.683905, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310071.602061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325462.049867, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325503.88631, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325506.004479, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412942.492135, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720458829.36376, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720458949.800013, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720458951.887504, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492407.820081, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492444.404348, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492446.466946, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575932.543872, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576033.410802, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576035.469127, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576036.44253, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720647287.059052, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720647289.160943, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720330899.088291, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720081793.462679, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720081976.131384, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720081976.187009, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720081980.325716, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720091170.691618, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720091356.840132, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720091358.928927, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720238399.047753, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567368.683366, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720583646.429286, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720330049.16818, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720578076.222297, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719972331.112716, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720051745.533132, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720146463.601388, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720474541.840768, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720051898.891617, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720173013.609275, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320493.657042, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720345690.851927, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720408818.140609, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720486964.900766, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720043728.363322, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311975.271982, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571578.431424, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719972681.535491, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720481018.937328, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720026382.553301, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720149100.706808, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720307942.507634, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570495.6023, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720488173.923373, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568447.027354, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720567270.126647, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720499324.726509, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719967975.358552, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720326137.056104, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720328587.433829, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720055336.001624, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138863.165013, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395924.519387, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720069032.516709, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720055010.518163, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720099339.150894, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720585549.317132, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720409221.504822, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720519728.003909, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567616.396835, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720244626.143033, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720408635.777109, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575490.310245, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720650559.825556, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720582328.399682, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720394085.218172, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720066065.444143, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720191993.66672, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491329.586545, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720071639.073353, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147406.207381, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311129.234658, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573354.037576, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720240131.733437, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984704.452873, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154844.587696, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720322613.231449, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569714.825725, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720486946.256934, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720647691.877446, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719993805.960143, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143738.25635, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309437.19401, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720398437.265534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720509793.976335, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720629661.586274, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720062670.596985, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720438472.029491, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720329032.038648, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719984110.370743, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719986035.664892, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720241225.374801, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720105075.810739, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720150414.362845, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308174.216706, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412581.759663, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567554.209717, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720537016.009206, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589963.468469, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720487391.820061, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719975756.8334, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155078.652264, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400698.199527, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496832.791723, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720018681.490249, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136925.765051, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720299976.82238, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569027.317754, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720154725.361924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243905.535885, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315512.512864, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720588095.521256, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719983442.727069, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720152453.391462, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720405182.158931, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720575807.583852, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720069878.030512, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720168504.534482, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720239119.238416, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720576430.211377, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719972965.48613, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720240976.867243, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404977.394327, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720537004.359466, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720487019.528315, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720581959.239135, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720652926.990055, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720052099.960777, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138855.98453, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138921.586511, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139014.744606, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139182.595009, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720139192.3206, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581909.908771, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720065955.899244, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236828.579322, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308640.597753, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720579634.738256, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719980159.276761, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308552.424302, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653256.063729, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719985271.443965, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720220543.115385, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315297.143816, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720330015.747888, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720481610.656596, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720224041.283015, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567371.834809, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720244217.827624, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720402557.505715, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502124.284452, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720415547.576014, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720531682.711315, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720407411.272993, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574508.629738, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720257290.163002, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492975.717018, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720144145.711511, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720401163.125022, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720355601.346282, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720572069.286814, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968339.260056, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968341.365428, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968343.993978, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968346.031381, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968349.431552, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719968351.559689, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719976134.941126, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719976278.477066, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719976280.56988, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052757.855887, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052759.915085, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720110094.313929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142517.707832, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142570.10559, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142572.151412, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142576.179553, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237055.807105, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237203.321556, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237205.419793, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720316912.566247, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317055.804333, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317057.925258, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317058.399149, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317060.481448, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393849.766518, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393921.300236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406796.853939, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406798.933918, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482599.505433, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482663.255581, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482665.27704, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492023.699542, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492025.737059, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500142.609638, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500250.895423, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720525828.241699, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720525830.335737, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720543473.185403, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720543629.193018, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720543631.258205, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566115.315069, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566235.252146, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566237.371673, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566239.622085, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566241.74061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652422.12376, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652589.161105, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720332940.235911, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720065527.859172, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720568368.543876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720635472.219669, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968828.538353, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720051948.377763, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720299205.556357, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720235830.179481, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235953.147018, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236018.20472, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236089.138704, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236119.593712, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720236141.83499, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311050.201652, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311052.280309, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395484.534496, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491406.080018, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491430.598198, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491432.661821, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572678.481313, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572808.45491, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572810.563889, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603175.70942, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603202.06502, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603204.156746, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652491.405509, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652598.039059, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652600.082367, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720153161.725292, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720494662.408865, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568597.855422, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720416466.753208, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719978991.390168, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720072031.976782, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720584690.251602, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720575076.950008, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720231712.798613, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720398045.987903, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720056840.047309, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720625851.477544, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720053429.359158, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053508.29626, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053570.605172, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720053639.380777, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066181.00997, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066215.053405, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720066217.116517, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143779.66573, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143781.713526, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222105.35254, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317654.056711, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317708.563828, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480329.549535, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480520.417693, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480522.54519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480523.499363, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577037.242221, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577039.306434, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720639329.717862, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720639469.331454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720639471.36127, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720024453.629276, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720316176.77774, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720068883.919311, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319773.101818, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586957.747953, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720056927.404781, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720054270.638059, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153565.870327, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720334693.538652, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720152641.309698, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720576318.23299, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720404934.034946, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720476937.980269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652925.317718, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720583121.659416, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719974918.036807, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720052839.789235, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309756.887443, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720214816.601474, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720628643.350003, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719990813.089809, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312746.860016, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720072040.294779, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720573666.820699, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720221192.01312, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720143165.437476, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719965593.95106, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062861.422969, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503564.270709, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720310060.645551, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720482309.217878, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720591036.349001, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720157768.51272, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720149445.473387, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720438026.869011, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720060489.013219, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720415886.629529, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720580867.871164, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720414273.276015, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720487097.033528, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719966569.062726, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719966533.368239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318867.369239, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720424434.84027, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566607.607309, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720608001.068576, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720062804.379267, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226534.49236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321084.499585, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720450358.303395, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577114.020932, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720138095.209939, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720109654.682718, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720109832.815741, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720109959.88633, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720110033.900336, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720110090.159457, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719973270.54798, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720404747.93651, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719975896.00888, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720412877.994145, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720488415.324703, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719979329.168652, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719979433.834943, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719979537.706541, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720054525.517489, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720054576.808031, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720054637.310552, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720008269.86362, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720228186.690288, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719980906.390651, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720049804.519108, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719982824.989151, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720052793.231176, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416383.522419, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576203.462386, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720141956.096351, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720501761.653384, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719968214.670337, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720061582.741936, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148352.805998, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720320650.836088, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720480540.757287, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720066746.296404, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720470635.779369, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720036143.99876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720235115.25383, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720325739.301864, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720366758.48691, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720579671.285769, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720406674.612278, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720569843.609239, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720060843.491976, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147665.305258, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720501529.904655, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720046373.265399, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720046375.332994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068144.411279, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720068261.195225, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720131629.331825, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720131717.731289, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143208.108341, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720224375.336718, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720224489.89131, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239983.991454, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720240023.957522, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720240026.023994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720288870.449116, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319014.330473, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319153.071162, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319155.11854, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720356008.754634, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720356170.017209, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720414281.753569, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720466888.126284, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720466890.175399, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496852.884055, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496900.157534, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496902.257177, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720517711.484252, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720517785.617389, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720517787.722386, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574636.301281, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574638.402501, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720631962.467861, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720632073.350096, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720222983.951049, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720416117.193584, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719971140.695348, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720135102.372106, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720241528.560118, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720494221.442123, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720321074.976216, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720409891.326419, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720048681.074873, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720048799.279747, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720048801.388645, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720078114.283264, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720078331.228227, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143813.123392, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720143818.771163, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235193.521271, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235195.596896, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325140.395885, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325267.478348, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411316.426439, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411410.991238, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720411413.049352, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585972.027756, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586043.355429, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586045.457795, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720615162.541609, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719966754.275194, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720490216.464205, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720553382.681907, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720002644.294528, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720230090.842106, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720146769.696788, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720165756.310512, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410912.566749, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570647.832366, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719976353.576494, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377185.297147, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377289.215042, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377308.468995, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377428.407697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377485.735576, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377529.508166, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377719.383399, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377809.666048, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720377903.918773, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719980213.693083, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720140384.252931, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720063871.378525, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720573199.935932, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719985832.719319, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720406386.34727, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720235695.246766, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720397629.747797, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719968874.938189, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719969009.652547, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985700.913806, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719985791.512554, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148300.05719, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148304.627225, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148306.685703, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227741.213642, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227808.775173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295172.811284, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295262.745855, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295264.827116, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295269.130924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295271.214758, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295276.000757, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295278.050173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720295281.951474, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314791.722567, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314793.809493, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314794.091414, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314796.180282, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720334621.693568, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720334651.208509, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720334653.289286, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405990.429231, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406072.368399, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406074.479232, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502938.778116, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720502940.865312, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575136.293441, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575193.500487, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720575195.593287, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584066.099625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584068.181406, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720401234.664166, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720338995.593562, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720569421.058122, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720152780.103003, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318021.21162, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568682.771219, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720153767.474128, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153989.99445, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154117.339532, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720154188.47243, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227169.047901, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227171.113334, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720290328.719511, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720290370.18464, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308949.583306, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309021.205367, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720309023.255742, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400031.238045, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400050.534361, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400052.591865, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720475517.057002, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720475631.221119, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489341.891834, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489520.813888, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720522911.41822, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720522980.415637, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720522982.44762, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590435.585175, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590601.259611, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590603.315457, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590604.638539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590606.730642, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720612053.860624, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720612129.921877, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720612132.011818, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720426949.173587, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720569102.034496, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720034790.744638, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720307075.973997, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720226287.705985, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397684.607266, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720488997.884315, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720228730.18975, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407495.769529, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486995.921451, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720489080.310875, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720579311.992295, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720138007.433538, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720243741.609597, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720528666.459324, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719970772.701878, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720141632.061506, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720068110.038208, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720047191.032235, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719976436.118248, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720307037.853977, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719972036.639217, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720057689.829017, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720110461.39165, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720507249.36072, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719973197.847086, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720069338.721539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720524537.017222, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720603176.268707, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720142471.621654, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720221877.173433, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720141771.947396, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720563222.366935, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720237444.558492, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720586951.821255, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720066787.226665, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138501.376918, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720332897.490345, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720498267.095353, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719979972.999784, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720326547.318274, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720156142.458551, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720222674.830191, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719976247.399205, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719976421.138728, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719976457.121053, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719976566.522486, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720060116.807539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142201.528128, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142320.790244, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142322.873716, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142323.209429, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720142325.32365, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720158309.47212, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720158464.699924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720158466.803077, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235827.780639, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235829.873017, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235831.516786, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720235833.64015, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308111.792929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308113.917634, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330424.153222, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330426.274619, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397440.529792, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397517.527169, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397519.567891, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489794.692916, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489888.559008, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489890.678539, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577363.385966, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720577493.034855, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720042932.668232, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720059740.224971, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720141837.883794, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405792.751871, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720050443.838424, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720124719.146549, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719974887.67444, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568466.68215, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720065592.314345, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720205463.888972, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720226332.701569, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396620.155135, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492327.218299, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720574416.447233, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720045016.618738, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720041923.403398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720041925.529856, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720041929.344695, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071082.001532, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071201.167727, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071203.259989, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720113938.478909, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720114019.141219, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147954.114345, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148058.186186, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148060.244565, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230463.28606, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230465.339869, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720306384.513301, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720306386.603107, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720327575.975525, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720327821.751969, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720327823.781901, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410348.159738, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410448.341114, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720457570.237639, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720457731.119754, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720457733.248545, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499264.385485, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499470.033411, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499472.085357, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720543986.94937, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570525.581032, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570749.619565, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585164.854344, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585249.748529, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585251.810485, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720489237.597076, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489298.656835, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489340.853931, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489414.715662, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489578.362748, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489722.080922, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489846.161597, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489902.616032, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489979.179271, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720226541.700259, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720459357.712795, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720137147.179349, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720241160.346244, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720393844.000636, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720233961.944441, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720475993.227865, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720339946.523179, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720314335.142585, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720307070.122528, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720396806.823553, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720134885.254524, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720582472.172677, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720064989.52196, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317471.54011, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720405569.646675, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720230240.375249, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719981989.67667, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982209.356573, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982211.412871, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719990729.511533, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719990731.571772, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052018.486278, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052084.895512, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720052086.959136, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063752.458627, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063775.402517, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720131365.952047, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720131512.217778, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720131514.344434, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720155954.588913, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720156049.221823, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326057.45718, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404760.882693, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404806.729924, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720404808.834418, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720416517.018963, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720494367.532053, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500247.551019, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500294.606063, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500296.694825, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500299.259697, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500301.365635, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572338.244531, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572428.794186, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572430.860491, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720600877.354363, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720601092.109844, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720601094.164843, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720230142.987461, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720040834.068992, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719984036.646786, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720138775.775437, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720337436.06649, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567415.54222, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720501680.278938, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720645969.459141, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719981148.135955, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574648.013669, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982323.222591, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720101646.380659, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720493833.121559, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719977634.84991, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720494761.805988, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720595943.849674, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720155432.624618, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720500643.020756, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584683.624928, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720245035.196003, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720313673.855042, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720381149.495776, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720019520.657419, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719981920.434976, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720128572.036838, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720136202.220094, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720279940.922158, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720462395.987553, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720653383.244, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653383.325, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653391.627, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653392.102, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653392.298, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653394.934, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653396.411, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653433.093, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653433.236, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653434.991, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653435.037, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653501.654, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653501.71, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653504.799, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653506.446, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720653507.872, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720654003.023, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720654003.148, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719977539.575178, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223726.13705, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720396336.894644, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720587683.68083, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720327049.710872, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720223003.678086, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320656.874702, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720149475.628567, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720228859.277837, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720049864.230497, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720198432.201466, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719975613.439717, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719975648.049123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056914.90013, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720057026.542911, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720061926.526142, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720062007.614611, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147419.43368, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720147421.485277, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234139.651394, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720234141.758276, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315191.984726, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315194.093018, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315195.836394, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395738.54726, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720395740.684533, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410342.218884, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410455.568303, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496479.412713, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720496636.329168, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568810.362519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720569040.475975, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652557.884167, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720652630.129755, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720233899.203213, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720463796.00711, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567454.878169, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720218589.331391, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720572246.733219, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585861.133309, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720030179.060188, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720330759.17762, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720494515.69797, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719979902.797865, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720070638.173492, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070819.083453, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070899.802295, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318683.767078, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318886.533145, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318966.57212, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318995.968059, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319139.50433, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720146380.443011, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567703.854081, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720485224.936769, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720039180.636756, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320703.675688, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720572877.111346, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720149009.624794, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720146066.037668, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720233446.585623, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720397647.223612, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720071535.98588, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720222696.675857, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720581710.534385, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720320564.297259, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720221596.179609, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720502714.197196, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720553799.408143, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720244362.654861, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720412405.21556, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720566429.648086, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720225993.003411, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720576860.143664, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720050680.82043, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719979231.190542, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720395944.084001, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720483644.896944, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720238837.512808, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400917.965225, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499924.896186, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719978670.650293, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312908.844749, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720064475.615309, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311005.200102, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720398033.682041, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1719974842.261587, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720070482.809945, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720492054.306253, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719985346.86067, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720494586.311794, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720151598.2787, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720243336.399964, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394460.006175, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584803.786632, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720044414.812182, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720161374.32603, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720242818.837344, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720407806.948096, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720511793.967125, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720177465.166679, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720152899.613121, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720144169.768087, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720050900.326256, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720592651.789908, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720136535.399876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720345016.561725, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720148677.039505, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720103982.765975, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720223275.492349, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719966246.265247, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720048787.249996, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588475.186395, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720406823.932911, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406854.864424, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406898.943281, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720106989.608336, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719965156.233365, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720156113.65034, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720237894.767081, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720236335.89358, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720311377.453215, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720406308.416613, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720580297.715893, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719983515.156201, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720243011.26844, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720412740.206646, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720573676.882026, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720069113.016836, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720065156.88711, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720342013.62189, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720414414.37316, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720576057.542994, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719965980.977528, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720328208.291947, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586256.843288, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719993285.557781, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720157474.360894, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720317049.692797, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720418157.354486, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720492206.117992, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720566094.344648, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719974058.930323, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720059173.893018, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720517061.661773, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720052300.009912, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720447926.535749, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720060153.321408, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720498576.79341, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720415193.154478, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720494529.74019, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719980354.732889, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980356.852338, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980359.805901, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980361.898886, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980364.204398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063622.210305, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063766.011158, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720063768.060823, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720134932.57792, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148426.91756, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720148428.987966, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237634.85931, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720237687.961173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720321596.679301, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394727.592533, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394743.278857, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720408408.443408, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720419213.527306, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720419321.981, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720419324.073269, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497577.385151, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497694.789568, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720497696.883431, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584999.597212, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585001.687849, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720585005.063862, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720134251.830614, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720407054.526951, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720543564.686466, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720395362.215692, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720500480.122778, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720058412.695383, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720228775.865928, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720503282.31697, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720614350.980502, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982519.149294, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982589.903207, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982591.966235, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982594.824529, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056059.106374, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056099.353137, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720056101.438857, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720084141.137944, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720084195.578773, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720136869.202173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223064.342828, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223120.591787, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223122.696149, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239556.237398, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239630.045363, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239632.137037, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720312988.468776, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313161.594176, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313163.656358, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413652.862676, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720413773.395596, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484458.010065, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484503.114542, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484505.173957, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720570920.862746, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571065.994777, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720571068.086575, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720138634.579801, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394701.653755, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720404840.88735, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720570759.329975, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720474997.255842, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719964981.812038, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719965079.656724, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719965081.766625, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720017945.346535, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720018196.228851, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720018198.332037, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071944.789981, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071989.860765, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720071991.963241, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226601.357382, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226662.671017, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226664.720854, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720226666.697991, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720245432.525672, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720245586.690365, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720245588.811888, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313288.75101, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313438.935319, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313440.997298, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325185.461926, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325279.708469, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325281.823994, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325284.895173, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720325286.963747, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720351212.007507, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720351417.722923, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720351419.786979, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410234.644402, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720410236.746729, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484087.598816, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720484089.656452, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720560975.588946, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720561062.767708, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576170.001406, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576274.339938, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720634969.318238, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720634971.383262, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720634973.669218, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720634975.727614, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720047138.987663, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720239116.860589, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720567216.089602, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720062114.160483, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719974901.32474, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720224712.94567, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719985511.407849, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720140363.584567, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720573348.34834, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720649971.95392, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720325668.53657, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720407800.484026, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720313988.784401, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720137608.121513, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230219.916298, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720576804.122481, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720060264.40999, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982324.891431, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719982326.95929, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072365.964045, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720072368.013382, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720185779.887725, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720185782.013458, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720230424.054008, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720329463.631365, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720329503.210461, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719978020.337077, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720378278.012205, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720198700.302556, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720417057.718199, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720584860.786802, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720627126.675399, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720072022.286212, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720366423.980574, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720221042.039954, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720060635.731519, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720210299.946067, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720283154.070272, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720402469.930097, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719972611.185894, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720227219.185837, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720565623.051185, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720060770.015072, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719979906.872722, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980094.376717, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1719980096.476308, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067152.682142, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067174.598435, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137635.975558, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720137733.593423, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720224539.774939, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720323664.982932, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400336.830381, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400497.747426, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720400499.843107, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486404.88152, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486460.387837, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720486462.465262, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720494960.521565, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720492283.522426, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720588131.39025, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719965172.184078, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720313653.224728, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720133961.331413, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719969914.979558, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720051155.959984, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720318569.685111, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720499729.951734, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720328273.411971, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719982315.965122, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720423276.150804, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720586911.740203, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1719968679.211527, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720063388.278848, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720416336.796001, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720398479.735494, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720493260.033312, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720489609.661573, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489700.750791, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720489717.546997, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720500732.208908, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720153118.225066, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720314031.634943, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720590337.724401, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720070140.554847, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720137932.433554, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719992154.926275, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320574.945082, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1719984916.520671, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720569849.178614, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720140614.641046, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720395184.350061, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720310387.035179, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720473940.199193, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720062920.051834, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720226181.474055, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720470329.222623, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720582334.499662, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720443828.896214, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720580682.756419, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720226425.344326, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310598.961662, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720589761.631011, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720584698.862455, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720164879.185564, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720323846.480885, "uuid", [], [1, 2, 3, 4, 5, 6])], + [(1720051096.071376, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720157299.452758, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720223524.412388, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720326592.782923, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720578100.065601, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720313647.455076, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720559337.211802, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1719981335.449573, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720067595.1521, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720319132.823969, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720491547.165147, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], [ - (1720019886.753884, [], [1, 2, 3, 4, 5, 6]), - (1720153101.556554, [], [1, 2, 3, 4, 5, 6]), - (1720313536.357232, [], [1, 2, 3, 4, 5, 6]), - (1720485395.202604, [], [1, 2, 3, 4, 5, 6]), - (1720568839.562655, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720310841.194378, [], [1, 2, 3, 4, 5, 6]), - (1720310912.574061, [], [1, 2, 3, 4, 5, 6]), - (1720310914.655803, [], [1, 2, 3, 4, 5, 6]), - (1720587828.804404, [], [1, 2, 3, 4, 5, 6]), - (1720588071.078858, [], [1, 2, 3, 4, 5, 6]), - (1720588073.115074, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720055953.618503, [], [1, 2, 3, 4, 5, 6]), - (1720223652.080905, [], [1, 2, 3, 4, 5, 6]), - (1720308372.703732, [], [1, 2, 3, 4, 5, 6]), - (1720624033.359415, [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720173756.125859, [], [1, 2, 3, 4, 5, 6]), - (1720315128.683231, [], [1, 2, 3, 4, 5, 6]), - (1720466410.646777, [], [1, 2, 3, 4, 5, 6]), - ], - [(1720157263.810637, [], [1, 2, 3, 4, 5, 6]), (1720235081.49838, [], [1, 2, 3, 4, 5, 6])], - [ - (1720229216.005254, [], [1, 2, 3, 4, 5, 6]), - (1720557735.625871, [], [1, 2, 3, 4, 5, 6]), - (1720627294.521232, [], [1, 2, 3, 4, 5, 6]), - ], + (1720019886.753884, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720153101.556554, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720313536.357232, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720485395.202604, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720568839.562655, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720310841.194378, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310912.574061, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720310914.655803, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720587828.804404, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588071.078858, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720588073.115074, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720055953.618503, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720223652.080905, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720308372.703732, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720624033.359415, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [ + (1720173756.125859, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720315128.683231, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720466410.646777, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], + [(1720157263.810637, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720235081.49838, "uuid", [], [1, 2, 3, 4, 5, 6])], + [ + (1720229216.005254, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720557735.625871, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720627294.521232, "uuid", [], [1, 2, 3, 4, 5, 6]), + ], [ - (1720394336.326148, [], [1, 2, 3, 4, 5, 6]), - (1720394382.775033, [], [1, 2, 3, 4, 5, 6]), - (1720394404.054186, [], [1, 2, 3, 4, 5, 6]), - (1720394488.655765, [], [1, 2, 3, 4, 5, 6]), - (1720394583.815862, [], [1, 2, 3, 4, 5, 6]), - (1720394609.744123, [], [1, 2, 3, 4, 5, 6]), - (1720394643.351845, [], [1, 2, 3, 4, 5, 6]), - (1720394661.447752, [], [1, 2, 3, 4, 5, 6]), - (1720394715.354794, [], [1, 2, 3, 4, 5, 6]), + (1720394336.326148, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394382.775033, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394404.054186, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394488.655765, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394583.815862, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394609.744123, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394643.351845, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394661.447752, "uuid", [], [1, 2, 3, 4, 5, 6]), + (1720394715.354794, "uuid", [], [1, 2, 3, 4, 5, 6]), ], ] for b in a: calculate_funnel_from_user_events(6, 1123200, "first_touch", "ordered", [[]], b) + + +def test3(): + data: list[Any] = [ + (1609545600, "11111111-1111-1111-1111-111111111111", [], [1]), + (1609632000, "21111111-1111-1111-1111-111111111111", [], [2]), + ] + + f = io.StringIO() + with redirect_stdout(f): + calculate_funnel_from_user_events(3, 1209600, "first_touch", "ordered", [[]], data) + result = f.getvalue() + + assert ( + result + == '{"result": [[1, [], [86400], [["11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111"], ["21111111-1111-1111-1111-111111111111", "21111111-1111-1111-1111-111111111111"], []]]]}\n' + ) + + +def test_strict_funnels_with_non_step_first_event(): + data: list[Any] = [ + (1609545500, "0b9f49ba-2c66-475f-b7b3-6e8acdb08a37", [], []), + (1609545600, "11111111-1111-1111-1111-111111111111", [], [1]), + (1609545780, "31111111-1111-1111-1111-111111111111", [], [2]), + (1609545840, "41111111-1111-1111-1111-111111111111", [], [2]), + ] + f = io.StringIO() + with redirect_stdout(f): + calculate_funnel_from_user_events(2, 1209600, "first_touch", "strict", [[]], data) + result = f.getvalue() + assert ( + result + == '{"result": [[1, [], [180], [["11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111"], ["31111111-1111-1111-1111-111111111111", "31111111-1111-1111-1111-111111111111"]]]]}\n' + ) + + +def test_strict_funnels_with_first_events_same_timestamp(): + data: list[Any] = [ + (1609545600, "0b9f49ba-2c66-475f-b7b3-6e8acdb08a37", [], []), + (1609545600, "11111111-1111-1111-1111-111111111111", [], [1]), + (1609545780, "31111111-1111-1111-1111-111111111111", [], [2]), + (1609545840, "41111111-1111-1111-1111-111111111111", [], [2]), + ] + f = io.StringIO() + with redirect_stdout(f): + calculate_funnel_from_user_events(2, 1209600, "first_touch", "strict", [[]], data) + result = f.getvalue() + assert ( + result + == '{"result": [[1, [], [180], [["11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111"], ["31111111-1111-1111-1111-111111111111", "31111111-1111-1111-1111-111111111111"]]]]}\n' + ) diff --git a/posthog/udf_versioner.py b/posthog/udf_versioner.py index a0d96a547b9f6..a9c7c5c383127 100644 --- a/posthog/udf_versioner.py +++ b/posthog/udf_versioner.py @@ -12,7 +12,7 @@ # 3. Copy the `user_defined_function.xml` file in the newly created version folder (e.g. `user_scripts/v4/user_defined_function.xml`) to the `posthog-cloud-infra` repo and deploy it # 4. After that deploy goes out, it is safe to land and deploy the changes to the `posthog` repo # If deploys aren't seamless, look into moving the action that copies the `user_scripts` folder to the clickhouse cluster earlier in the deploy process -UDF_VERSION = 0 # Last modified by: @aspicer, 2024-09-20 +UDF_VERSION = 1 # Last modified by: @aspicer, 2024-09-27 CLICKHOUSE_XML_FILENAME = "user_defined_function.xml" ACTIVE_XML_CONFIG = "../../docker/clickhouse/user_defined_function.xml" diff --git a/posthog/user_scripts/aggregate_funnel.py b/posthog/user_scripts/aggregate_funnel.py index 162918a819625..1c40a993f91df 100755 --- a/posthog/user_scripts/aggregate_funnel.py +++ b/posthog/user_scripts/aggregate_funnel.py @@ -15,7 +15,7 @@ def parse_args(line): str(args["breakdown_attribution_type"]), str(args["funnel_order_type"]), args["prop_vals"], # Array(Array(String)) - args["value"], # Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) + args["value"], # Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) ] @@ -23,6 +23,10 @@ def parse_args(line): class EnteredTimestamp: timestamp: Any timings: Any + uuids: list[str] + + +MAX_REPLAY_EVENTS = 10 # each one can be multiple steps here @@ -30,7 +34,7 @@ class EnteredTimestamp: # This function is defined for Clickhouse in user_defined_functions.xml along with types # num_steps is the total number of steps in the funnel # conversion_window_limit is in seconds -# events is a array of tuples of (timestamp, breakdown, [steps]) +# events is an array of tuples of (timestamp, breakdown, [steps]) # steps is an array of integers which represent the steps that this event qualifies for. it looks like [1,3,5,6]. # negative integers represent an exclusion on that step. each event is either all exclusions or all steps. def calculate_funnel_from_user_events( @@ -39,18 +43,18 @@ def calculate_funnel_from_user_events( breakdown_attribution_type: str, funnel_order_type: str, prop_vals: list[Any], - events: Sequence[tuple[float, list[str] | int | str, list[int]]], + events: Sequence[tuple[float, str, list[str] | int | str, list[int]]], ): - default_entered_timestamp = EnteredTimestamp(0, []) + default_entered_timestamp = EnteredTimestamp(0, [], []) max_step = [0, default_entered_timestamp] # If the attribution mode is a breakdown step, set this to the integer that represents that step breakdown_step = int(breakdown_attribution_type[5:]) if breakdown_attribution_type.startswith("step_") else None # This function returns an Array. We build up an array of strings to return here. - results: list[tuple[int, Any, list[float]]] = [] + results: list[tuple[int, Any, list[float], list[list[str]]]] = [] # Process an event. If this hits an exclusion, return False, else return True. - def process_event(timestamp, breakdown, steps, *, entered_timestamp, prop_val) -> bool: + def process_event(timestamp, uuid, breakdown, steps, *, entered_timestamp, prop_val, event_uuids) -> bool: # iterate the steps in reverse so we don't count this event multiple times for step in reversed(steps): exclusion = False @@ -61,24 +65,30 @@ def process_event(timestamp, breakdown, steps, *, entered_timestamp, prop_val) - in_match_window = timestamp - entered_timestamp[step - 1].timestamp <= conversion_window_limit_seconds already_reached_this_step_with_same_entered_timestamp = ( entered_timestamp[step].timestamp == entered_timestamp[step - 1].timestamp + and entered_timestamp[step].timestamp != 0 ) if in_match_window and not already_reached_this_step_with_same_entered_timestamp: if exclusion: - results.append((-1, prop_val, [])) + results.append((-1, prop_val, [], [])) return False is_unmatched_step_attribution = ( breakdown_step is not None and step == breakdown_step - 1 and prop_val != breakdown ) if not is_unmatched_step_attribution: entered_timestamp[step] = replace( - entered_timestamp[step - 1], timings=[*entered_timestamp[step - 1].timings, timestamp] + entered_timestamp[step - 1], + timings=[*entered_timestamp[step - 1].timings, timestamp], + uuids=[*entered_timestamp[step - 1].uuids, uuid], ) + if len(event_uuids[step - 1]) < MAX_REPLAY_EVENTS - 1: + event_uuids[step - 1].append(uuid) + # TODO: If this is strict, and this didn't match, we should remove this if step > max_step[0]: max_step[:] = (step, entered_timestamp[step]) if funnel_order_type == "strict": - for i in range(len(entered_timestamp)): + for i in range(1, len(entered_timestamp)): if i not in steps: entered_timestamp[i] = default_entered_timestamp @@ -90,23 +100,43 @@ def loop_prop_val(prop_val): # entered_timestamp = [(0, "", [])] * (num_steps + 1) max_step[:] = [0, default_entered_timestamp] entered_timestamp: list[EnteredTimestamp] = [default_entered_timestamp] * (num_steps + 1) + event_uuids: list[list[str]] = [[] for _ in range(num_steps)] def add_max_step(): - i = cast(int, max_step[0]) + final_index = cast(int, max_step[0]) final = cast(EnteredTimestamp, max_step[1]) - results.append((i - 1, prop_val, [final.timings[i] - final.timings[i - 1] for i in range(1, i)])) + for i in range(final_index): + # if len(event_uuids[i]) >= MAX_REPLAY_EVENTS and final.uuids[i] not in event_uuids[i]: + # Always put the actual event uuids first, we use it to extract timestamps + # This might create duplicates, but that's fine (we can remove it in clickhouse) + event_uuids[i].insert(0, final.uuids[i]) + results.append( + ( + final_index - 1, + prop_val, + [final.timings[i] - final.timings[i - 1] for i in range(1, final_index)], + event_uuids, + ) + ) filtered_events = ( - ((timestamp, breakdown, steps) for (timestamp, breakdown, steps) in events if breakdown == prop_val) + ( + (timestamp, uuid, breakdown, steps) + for (timestamp, uuid, breakdown, steps) in events + if breakdown == prop_val + ) if breakdown_attribution_type == "all_events" else events ) for timestamp, events_with_same_timestamp_iterator in groupby(filtered_events, key=lambda x: x[0]): events_with_same_timestamp = tuple(events_with_same_timestamp_iterator) - entered_timestamp[0] = EnteredTimestamp(timestamp, []) + entered_timestamp[0] = EnteredTimestamp(timestamp, [], []) if len(events_with_same_timestamp) == 1: if not process_event( - *events_with_same_timestamp[0], entered_timestamp=entered_timestamp, prop_val=prop_val + *events_with_same_timestamp[0], + entered_timestamp=entered_timestamp, + prop_val=prop_val, + event_uuids=event_uuids, ): return else: @@ -114,11 +144,14 @@ def add_max_step(): # We play all of their permutations and most generously take the ones that advanced the furthest # This has quite bad performance, and can probably be optimized through clever but annoying logic # but shouldn't be hit too often + # This could potentially cause the same event to be added to the matching events multiple times entered_timestamps = [] for events_group_perm in permutations(events_with_same_timestamp): entered_timestamps.append(list(entered_timestamp)) for event in events_group_perm: - if not process_event(*event, entered_timestamp=entered_timestamps[-1], prop_val=prop_val): + if not process_event( + *event, entered_timestamp=entered_timestamps[-1], prop_val=prop_val, event_uuids=event_uuids + ): # If any of the permutations hits an exclusion, we exclude this user. # This isn't an important implementation detail and we could do something smarter here. return diff --git a/posthog/user_scripts/aggregate_funnel_test.py b/posthog/user_scripts/aggregate_funnel_test.py index e0689b82af21c..3eff43269c58e 100755 --- a/posthog/user_scripts/aggregate_funnel_test.py +++ b/posthog/user_scripts/aggregate_funnel_test.py @@ -3,11 +3,12 @@ from aggregate_funnel import calculate_funnel_from_user_events, parse_args import sys +import traceback if __name__ == "__main__": for line in sys.stdin: try: calculate_funnel_from_user_events(*parse_args(line)) except Exception as e: - print(json.dumps({"result": json.dumps(str(e))}), end="\n") # noqa: T201 + print(json.dumps({"result": json.dumps(str(e) + traceback.format_exc())}), end="\n") # noqa: T201 sys.stdout.flush() diff --git a/posthog/user_scripts/latest_user_defined_function.xml b/posthog/user_scripts/latest_user_defined_function.xml index 6f8f787da15c1..cec2d0d340802 100644 --- a/posthog/user_scripts/latest_user_defined_function.xml +++ b/posthog/user_scripts/latest_user_defined_function.xml @@ -1,5 +1,5 @@ - executable aggregate_funnel @@ -570,4 +570,289 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_array_trends_test.py + + executable + aggregate_funnel_v1 + Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) + result + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(Nullable(String)) + prop_vals + + + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel.py + + + + executable + aggregate_funnel_cohort_v1 + Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) + result + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(UInt64) + prop_vals + + + Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_cohort.py + + + + executable + aggregate_funnel_array_v1 + Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) + result + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(Array(String)) + prop_vals + + + Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_array.py + + + + executable + aggregate_funnel_test_v1 + String + result + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(Array(String)) + prop_vals + + + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_test.py + + + + executable + aggregate_funnel_trends_v1 + Array(Tuple(DateTime, Int8, Nullable(String))) + result + + UInt8 + from_step + + + UInt8 + num_steps + + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(Nullable(String)) + prop_vals + + + Array(Tuple(Nullable(Float64), Nullable(DateTime), Nullable(String), Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_trends.py + + + + executable + aggregate_funnel_array_trends_v1 + + Array(Tuple(DateTime, Int8, Array(String))) + result + + UInt8 + from_step + + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(Array(String)) + prop_vals + + + Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_array_trends.py + + + + executable + aggregate_funnel_cohort_trends_v1 + + Array(Tuple(DateTime, Int8, UInt64)) + result + + UInt8 + from_step + + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(UInt64) + prop_vals + + + Array(Tuple(Nullable(Float64), Nullable(DateTime), UInt64, Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_cohort_trends.py + + + + executable + aggregate_funnel_array_trends_test_v1 + String + result + + UInt8 + from_step + + + UInt8 + num_steps + + + UInt64 + conversion_window_limit + + + String + breakdown_attribution_type + + + String + funnel_order_type + + + Array(Array(String)) + prop_vals + + + Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) + value + + JSONEachRow + v1/aggregate_funnel_array_trends_test.py + \ No newline at end of file From 5ee52e899c57a7b39e5391faf46db63b597808d3 Mon Sep 17 00:00:00 2001 From: Sandy Spicer Date: Tue, 1 Oct 2024 15:15:49 -0700 Subject: [PATCH 02/10] rust funnel udfs --- docker-compose.base.yml | 2 +- .../docker-entrypoint-initdb.d/init-db.sh | 3 +- docker/clickhouse/user_defined_function.xml | 14 +- funnel-udf/.gitignore | 1 + funnel-udf/Cargo.lock | 152 + funnel-udf/Cargo.toml | 14 + funnel-udf/src/main.rs | 256 + posthog/hogql/functions/mapping.py | 1 + .../test_funnel_correlation_actors_udf.ambr | 22 +- .../test_funnel_correlation_udf.ambr | 172 +- .../test_funnel_persons_udf.ambr | 6 +- .../test_funnel_strict_persons_udf.ambr | 6 +- .../__snapshots__/test_funnel_strict_udf.ambr | 280 +- .../__snapshots__/test_funnel_trends_udf.ambr | 6 +- .../test/__snapshots__/test_funnel_udf.ambr | 32 +- .../test_funnel_time_to_convert.ambr | 254 - .../user_scripts/test_aggregate_funnel.py | 4259 ----------------- posthog/udf_versioner.py | 8 +- posthog/user_scripts/aggregate_funnel | Bin 0 -> 680624 bytes posthog/user_scripts/aggregate_funnel.py | 177 - .../user_scripts/aggregate_funnel_array.py | 9 - .../user_scripts/aggregate_funnel_cohort.py | 9 - posthog/user_scripts/aggregate_funnel_test.py | 4 +- .../latest_user_defined_function.xml | 343 +- posthog/user_scripts/v0/aggregate_funnel | Bin 0 -> 680624 bytes posthog/user_scripts/v0/aggregate_funnel.py | 144 - .../user_scripts/v0/aggregate_funnel_array.py | 9 - .../v0/aggregate_funnel_cohort.py | 9 - .../user_scripts/v0/aggregate_funnel_test.py | 7 +- .../user_scripts/v0/user_defined_function.xml | 58 +- posthog/user_scripts/v1/aggregate_funnel.py | 177 - .../user_scripts/v1/aggregate_funnel_array.py | 9 - .../v1/aggregate_funnel_array_trends.py | 9 - .../v1/aggregate_funnel_array_trends_test.py | 13 - .../v1/aggregate_funnel_cohort.py | 9 - .../v1/aggregate_funnel_cohort_trends.py | 9 - .../user_scripts/v1/aggregate_funnel_test.py | 14 - .../v1/aggregate_funnel_trends.py | 131 - .../user_scripts/v1/user_defined_function.xml | 858 ---- 39 files changed, 790 insertions(+), 6696 deletions(-) create mode 100644 funnel-udf/.gitignore create mode 100644 funnel-udf/Cargo.lock create mode 100644 funnel-udf/Cargo.toml create mode 100644 funnel-udf/src/main.rs delete mode 100644 posthog/test/user_scripts/test_aggregate_funnel.py create mode 100755 posthog/user_scripts/aggregate_funnel delete mode 100755 posthog/user_scripts/aggregate_funnel.py delete mode 100755 posthog/user_scripts/aggregate_funnel_array.py delete mode 100755 posthog/user_scripts/aggregate_funnel_cohort.py create mode 100755 posthog/user_scripts/v0/aggregate_funnel delete mode 100755 posthog/user_scripts/v0/aggregate_funnel.py delete mode 100755 posthog/user_scripts/v0/aggregate_funnel_array.py delete mode 100755 posthog/user_scripts/v0/aggregate_funnel_cohort.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_array.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_array_trends.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_array_trends_test.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_cohort.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_cohort_trends.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_test.py delete mode 100755 posthog/user_scripts/v1/aggregate_funnel_trends.py delete mode 100644 posthog/user_scripts/v1/user_defined_function.xml diff --git a/docker-compose.base.yml b/docker-compose.base.yml index 4b17a35977555..137416e40422c 100644 --- a/docker-compose.base.yml +++ b/docker-compose.base.yml @@ -79,7 +79,7 @@ services: # Note: please keep the default version in sync across # `posthog` and the `charts-clickhouse` repos # - image: ${CLICKHOUSE_SERVER_IMAGE:-clickhouse/clickhouse-server:23.12.6.19-alpine} + image: ${CLICKHOUSE_SERVER_IMAGE:-clickhouse/clickhouse-server:23.12.6.19} restart: on-failure zookeeper: diff --git a/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh b/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh index 4141e3345d05b..187ec4269a15d 100755 --- a/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh +++ b/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh @@ -1,5 +1,6 @@ #!/bin/bash set -e -apk add python3 +apt-get update +apt-get -y install python3 cp -r /idl/* /var/lib/clickhouse/format_schemas/ diff --git a/docker/clickhouse/user_defined_function.xml b/docker/clickhouse/user_defined_function.xml index a3175f8e17e48..9b58b380066e6 100644 --- a/docker/clickhouse/user_defined_function.xml +++ b/docker/clickhouse/user_defined_function.xml @@ -29,7 +29,8 @@ value JSONEachRow - aggregate_funnel.py + aggregate_funnel + 600 @@ -62,7 +63,8 @@ value JSONEachRow - aggregate_funnel_cohort.py + aggregate_funnel + 600 @@ -95,7 +97,8 @@ value JSONEachRow - aggregate_funnel_array.py + aggregate_funnel + 600 @@ -129,6 +132,7 @@ JSONEachRow aggregate_funnel_test.py + 600 @@ -170,6 +174,7 @@ JSONEachRow aggregate_funnel_trends.py + 600 @@ -208,6 +213,7 @@ JSONEachRow aggregate_funnel_array_trends.py + 600 @@ -246,6 +252,7 @@ JSONEachRow aggregate_funnel_cohort_trends.py + 600 @@ -283,5 +290,6 @@ JSONEachRow aggregate_funnel_array_trends_test.py + 600 \ No newline at end of file diff --git a/funnel-udf/.gitignore b/funnel-udf/.gitignore new file mode 100644 index 0000000000000..ea8c4bf7f35f6 --- /dev/null +++ b/funnel-udf/.gitignore @@ -0,0 +1 @@ +/target diff --git a/funnel-udf/Cargo.lock b/funnel-udf/Cargo.lock new file mode 100644 index 0000000000000..c58e632f4bfac --- /dev/null +++ b/funnel-udf/Cargo.lock @@ -0,0 +1,152 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "funnels" +version = "0.1.0" +dependencies = [ + "itertools", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/funnel-udf/Cargo.toml b/funnel-udf/Cargo.toml new file mode 100644 index 0000000000000..b5bdd57d5e67d --- /dev/null +++ b/funnel-udf/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "funnels" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = { version = "1.0.104", features = ["derive"] } +serde_json = "1.0.48" +itertools = "0.11" +uuid = { version = "1.10.0", features = ["v4", "serde"] } + + +[profile.release] +lto = true diff --git a/funnel-udf/src/main.rs b/funnel-udf/src/main.rs new file mode 100644 index 0000000000000..78775a9dd35b3 --- /dev/null +++ b/funnel-udf/src/main.rs @@ -0,0 +1,256 @@ +use serde::{Deserialize, Serialize}; +use serde_json::json; +use std::io::{self, BufRead, Write}; +use std::iter::repeat; +use itertools::Itertools; +use uuid::Uuid; + +#[derive(Clone, PartialEq, Deserialize, Serialize)] +#[serde(untagged)] +enum PropVal { + String(String), + Vec(Vec), + Int(u32), +} + +#[derive(Clone, Deserialize)] +struct EnteredTimestamp { + timestamp: f64, + timings: Vec, + uuids: Vec, +} + +#[derive(Clone, Deserialize)] +struct Event { + timestamp: f64, + uuid: Uuid, + breakdown: PropVal, + steps: Vec, +} + +#[derive(Deserialize)] +struct Args { + num_steps: i32, + conversion_window_limit: u64, + breakdown_attribution_type: String, + funnel_order_type: String, + prop_vals: Vec, + value: Vec, +} + +#[derive(Serialize)] +struct Result(i32, PropVal, Vec, Vec>); + +const MAX_REPLAY_EVENTS: usize = 10; + +#[inline(always)] +fn parse_args(line: &str) -> Args { + serde_json::from_str(line).expect("Invalid JSON input") +} + +#[inline(always)] +fn calculate_funnel_from_user_events( + num_steps: i32, + conversion_window_limit_seconds: u64, + breakdown_attribution_type: &str, + funnel_order_type: &str, + prop_vals: Vec, + events: Vec, +) -> Vec { + let default_entered_timestamp = EnteredTimestamp { + timestamp: 0.0, + timings: vec![], + uuids: vec![], + }; + let breakdown_step = if breakdown_attribution_type.starts_with("step_") { + breakdown_attribution_type[5..].parse::().ok() + } else { + None + }; + + let mut results: Vec = Vec::with_capacity(prop_vals.len()); + + for prop_val in prop_vals { + let mut max_step = (0, default_entered_timestamp.clone()); + let mut entered_timestamp = vec![default_entered_timestamp.clone(); (num_steps + 1) as usize]; + let mut event_uuids: Vec> = repeat(Vec::new()).take(num_steps as usize).collect(); + let mut add_max_step = true; + + let filtered_events = events.iter() + .filter(|e| { + if breakdown_attribution_type == "all_events" { + e.breakdown == prop_val + } else { + true + } + }) + .group_by(|e| e.timestamp); + + for (timestamp, events_with_same_timestamp) in &filtered_events { + let events_with_same_timestamp: Vec<_> = events_with_same_timestamp.collect(); + entered_timestamp[0] = EnteredTimestamp { + timestamp, + timings: vec![], + uuids: vec![], + }; + + if events_with_same_timestamp.len() == 1 { + if !process_event( + &events_with_same_timestamp[0], + &mut entered_timestamp, + &prop_val, + &mut event_uuids, + conversion_window_limit_seconds, + funnel_order_type, + &mut max_step, + breakdown_step, + &mut results, + ) { + add_max_step = false; + break; + } + } else { + // Handle permutations for events with the same timestamp + let mut entered_timestamps: Vec<_> = vec![]; + for perm in events_with_same_timestamp.iter().permutations(events_with_same_timestamp.len()) { + entered_timestamps.push(entered_timestamp.clone()); + for event in perm { + if !process_event( + &event, + &mut entered_timestamps.last_mut().unwrap(), + &prop_val, + &mut event_uuids, + conversion_window_limit_seconds, + funnel_order_type, + &mut max_step, + breakdown_step, + &mut results, + ) { + add_max_step = false; + break; + } + } + } + for i in 0..entered_timestamp.len() { + entered_timestamp[i] = entered_timestamps.iter().max_by_key(|x| x[i].timestamp as i32).unwrap()[i].clone(); + } + } + + if entered_timestamp[num_steps as usize].timestamp > 0.0 { + break; + } + } + + if add_max_step { + let final_index = max_step.0; + let final_value = &max_step.1; + + for i in 0..final_index { + //if event_uuids[i].len() >= MAX_REPLAY_EVENTS && !event_uuids[i].contains(&final_value.uuids[i]) { + // Always put the actual event uuids first, we use it to extract timestamps + // This might create duplicates, but that's fine (we can remove it in clickhouse) + event_uuids[i].insert(0, final_value.uuids[i].clone()); + } + results.push(Result( + final_index as i32 - 1, + prop_val, + final_value.timings.windows(2).map(|w| w[1] - w[0]).collect(), + event_uuids + )) + } + } + results +} + +#[inline(always)] +fn process_event( + event: &Event, + entered_timestamp: &mut Vec, + prop_val: &PropVal, + event_uuids: &mut Vec>, + conversion_window_limit_seconds: u64, + funnel_order_type: &str, + max_step: &mut (usize, EnteredTimestamp), + breakdown_step: Option, + results: &mut Vec +) -> bool { + + for step in event.steps.iter().rev() { + let mut exclusion = false; + let step = (if *step < 0 { + exclusion = true; + -*step + } else { + *step + }) as usize; + + let in_match_window = (event.timestamp - entered_timestamp[step - 1].timestamp) <= conversion_window_limit_seconds as f64; + let already_reached_this_step = entered_timestamp[step].timestamp == entered_timestamp[step - 1].timestamp + && entered_timestamp[step].timestamp != 0.0; + + if in_match_window && !already_reached_this_step { + if exclusion { + results.push(Result ( -1, prop_val.clone(), vec![], vec![] )); + return false; + } + let is_unmatched_step_attribution = breakdown_step.map( |breakdown_step| step == breakdown_step - 1 ).unwrap_or(false) && *prop_val != event.breakdown; + if !is_unmatched_step_attribution { + entered_timestamp[step] = EnteredTimestamp { + timestamp: entered_timestamp[step - 1].timestamp, + timings: { + let mut timings = entered_timestamp[step - 1].timings.clone(); + timings.push(event.timestamp); + timings + }, + uuids: { + let mut uuids = entered_timestamp[step - 1].uuids.clone(); + uuids.push(event.uuid); + uuids + }, + }; + if event_uuids[step - 1].len() < MAX_REPLAY_EVENTS - 1 { + event_uuids[step - 1].push(event.uuid); + } + } + if step > max_step.0 { + *max_step = (step, entered_timestamp[step].clone()); + } + } + } + + if funnel_order_type == "strict" { + for i in 1..entered_timestamp.len() { + if !event.steps.contains(&(i as i32)) { + entered_timestamp[i] = EnteredTimestamp { + timestamp: 0.0, + timings: vec![], + uuids: vec![], + }; + } + } + } + + true +} + +fn main() { + let stdin = io::stdin(); + let mut stdout = io::stdout(); + + for line in stdin.lock().lines() { + if let Ok(line) = line { + let args = parse_args(&line); + let result = calculate_funnel_from_user_events( + args.num_steps, + args.conversion_window_limit, + &args.breakdown_attribution_type, + &args.funnel_order_type, + args.prop_vals, + args.value + ); + let output = json!({ "result": result }); + writeln!(stdout, "{}", output).unwrap(); + stdout.flush().unwrap(); + } + } +} \ No newline at end of file diff --git a/posthog/hogql/functions/mapping.py b/posthog/hogql/functions/mapping.py index 4d81087524316..75512d75f4945 100644 --- a/posthog/hogql/functions/mapping.py +++ b/posthog/hogql/functions/mapping.py @@ -1040,6 +1040,7 @@ def compare_types(arg_types: list[ConstantType], sig_arg_types: tuple[ConstantTy "aggregate_funnel_test": HogQLFunctionMeta("aggregate_funnel_test", 6, 6, aggregate=False), } # We want CI to fail if there is a breaking change and the version hasn't been incremented +# Remove UDF versioning for now if is_cloud() or is_ci(): from posthog.udf_versioner import augment_function_name diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr index 0162d9d172265..c55def5ee7da4 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_actors_udf.ambr @@ -25,7 +25,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -76,7 +76,7 @@ JOIN (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 FROM events AS e @@ -147,7 +147,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -199,7 +199,7 @@ JOIN (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[3][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1, if(equals(e.event, 'insight updated'), 1, 0) AS step_2 FROM events AS e @@ -262,7 +262,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -316,7 +316,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 FROM events AS e @@ -385,7 +385,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -441,7 +441,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -495,7 +495,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 FROM events AS e @@ -567,7 +567,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -621,7 +621,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, '$pageview'), 1, 0) AS step_0, if(equals(e.event, 'insight analyzed'), 1, 0) AS step_1 FROM events AS e diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr index 5dd4947101474..e1ddaaabb7ece 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_correlation_udf.ambr @@ -21,7 +21,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -68,7 +68,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -126,7 +126,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -186,7 +186,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -244,7 +244,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -298,7 +298,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -370,7 +370,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -424,7 +424,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -496,7 +496,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -550,7 +550,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -622,7 +622,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -676,7 +676,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -748,7 +748,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -808,7 +808,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -866,7 +866,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -920,7 +920,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -992,7 +992,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1046,7 +1046,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -1118,7 +1118,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1172,7 +1172,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -1244,7 +1244,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1298,7 +1298,7 @@ FROM (SELECT aggregation_target AS actor_id, matched_events_array[plus(step_reached, 1)] AS matching_events, (matched_events_array[1][1]).1 AS timestamp, nullIf((matched_events_array[2][1]).1, 0) AS final_timestamp, (matched_events_array[1][1]).1 AS first_timestamp, steps AS steps, final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, af_tuple.3 AS timings, af_tuple.4 AS matched_event_uuids_array_array, groupArray(tuple(timestamp, uuid, `$session_id`, `$window_id`)) AS user_events, mapFromArrays(arrayMap(x -> x.2, user_events), user_events) AS user_events_map, arrayMap(matched_event_uuids_array -> arrayMap(event_uuid -> user_events_map[event_uuid], arrayDistinct(matched_event_uuids_array)), matched_event_uuids_array_array) AS matched_events_array, aggregation_target AS aggregation_target FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, e.uuid AS uuid, e.`$session_id` AS `$session_id`, e.`$window_id` AS `$window_id`, if(equals(e.event, 'user signed up'), 1, 0) AS step_0, if(equals(e.event, 'paid'), 1, 0) AS step_1 FROM events AS e @@ -1372,7 +1372,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1413,7 +1413,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1466,7 +1466,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1507,7 +1507,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1555,7 +1555,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1595,7 +1595,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1645,7 +1645,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1707,7 +1707,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1769,7 +1769,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1831,7 +1831,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1891,7 +1891,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1939,7 +1939,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1997,7 +1997,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2059,7 +2059,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2119,7 +2119,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2159,7 +2159,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2209,7 +2209,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2271,7 +2271,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2333,7 +2333,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2395,7 +2395,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2455,7 +2455,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2503,7 +2503,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2561,7 +2561,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2623,7 +2623,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2686,7 +2686,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2738,7 +2738,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2787,7 +2787,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2856,7 +2856,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2925,7 +2925,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2994,7 +2994,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3065,7 +3065,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3117,7 +3117,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3168,7 +3168,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3220,7 +3220,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3269,7 +3269,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3338,7 +3338,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3407,7 +3407,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3476,7 +3476,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3547,7 +3547,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3599,7 +3599,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3650,7 +3650,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3702,7 +3702,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3751,7 +3751,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3820,7 +3820,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3889,7 +3889,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -3958,7 +3958,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4029,7 +4029,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4081,7 +4081,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4132,7 +4132,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4184,7 +4184,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4233,7 +4233,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4302,7 +4302,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4371,7 +4371,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4440,7 +4440,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4511,7 +4511,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4563,7 +4563,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4614,7 +4614,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4666,7 +4666,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4715,7 +4715,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4784,7 +4784,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4853,7 +4853,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4922,7 +4922,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -4993,7 +4993,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -5045,7 +5045,7 @@ final_timestamp, first_timestamp FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr index 53ead043ec8e9..eb95b923f5929 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr @@ -8,7 +8,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[1] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -81,7 +81,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -154,7 +154,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr index 91c999226376f..d82701546b9ea 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr @@ -8,7 +8,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[1] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -81,7 +81,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -154,7 +154,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr index 4bd394de540b2..8745e81203e3e 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr @@ -1135,38 +1135,38 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS step_reached, - plus(af_tuple.1, 1) AS steps, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS af, af_tuple.2 AS breakdown, - af_tuple.3 AS timings, - aggregation_target AS aggregation_target + af_tuple.3 AS timings FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - uuid AS uuid, - `$session_id` AS `$session_id`, - `$window_id` AS `$window_id`, - step_0 AS step_0, - step_1 AS step_1, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + exclusion_0 AS exclusion_0, + exclusion_1 AS exclusion_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - e.uuid AS uuid, - e.`$session_id` AS `$session_id`, - e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, + 0 AS exclusion_0, + 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1180,7 +1180,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + HAVING ifNull(greaterOrEquals(af, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1203,40 +1203,40 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS step_reached, - plus(af_tuple.1, 1) AS steps, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS af, af_tuple.2 AS breakdown, - af_tuple.3 AS timings, - aggregation_target AS aggregation_target + af_tuple.3 AS timings FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - uuid AS uuid, - `$session_id` AS `$session_id`, - `$window_id` AS `$window_id`, - step_0 AS step_0, - step_1 AS step_1, - prop_basic AS prop_basic, - prop_0 AS prop_0, - prop_1 AS prop_1, - prop, - prop_vals AS prop_vals, - prop + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + exclusion_0 AS exclusion_0, + exclusion_1 AS exclusion_1, + prop_basic AS prop_basic, + prop_0 AS prop_0, + prop_1 AS prop_1, + prop, + prop_vals AS prop_vals, + prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - e.uuid AS uuid, - e.`$session_id` AS `$session_id`, - e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(and(equals(e.event, 'buy'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', ''), 'xyz'), 0)), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, + 0 AS exclusion_0, + 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, if(ifNull(equals(step_0, 1), 0), prop_basic, []) AS prop_0, if(ifNull(equals(step_1, 1), 0), prop_basic, []) AS prop_1, @@ -1255,7 +1255,7 @@ WHERE ifNull(notEquals(prop, []), isNotNull(prop) or isNotNull([]))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + HAVING ifNull(greaterOrEquals(af, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1278,38 +1278,38 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, + (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, - af_tuple.1 AS step_reached, - plus(af_tuple.1, 1) AS steps, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + af_tuple.1 AS af, af_tuple.2 AS breakdown, - af_tuple.3 AS timings, - aggregation_target AS aggregation_target + af_tuple.3 AS timings FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - uuid AS uuid, - `$session_id` AS `$session_id`, - `$window_id` AS `$window_id`, - step_0 AS step_0, - step_1 AS step_1, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + exclusion_0 AS exclusion_0, + exclusion_1 AS exclusion_1, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['', '']) AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - e.uuid AS uuid, - e.`$session_id` AS `$session_id`, - e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'buy'), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, + 0 AS exclusion_0, + 0 AS exclusion_1, [ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', '')), ''), ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$version'), ''), 'null'), '^"|"$', '')), '')] AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1323,7 +1323,7 @@ HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS e__override ON equals(e.distinct_id, e__override.distinct_id) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + HAVING ifNull(greaterOrEquals(af, 0), 0)) GROUP BY breakdown ORDER BY step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1352,7 +1352,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1420,7 +1420,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1495,7 +1495,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1560,42 +1560,46 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS step_reached, - plus(af_tuple.1, 1) AS steps, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS af, af_tuple.2 AS breakdown, - af_tuple.3 AS timings, - aggregation_target AS aggregation_target + af_tuple.3 AS timings FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - uuid AS uuid, - `$session_id` AS `$session_id`, - `$window_id` AS `$window_id`, - step_0 AS step_0, - step_1 AS step_1, - step_2 AS step_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + step_2 AS step_2, + latest_2 AS latest_2, + exclusion_0 AS exclusion_0, + exclusion_1 AS exclusion_1, + exclusion_2 AS exclusion_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e.`$group_0` AS aggregation_target, - e.uuid AS uuid, - e.`$session_id` AS `$session_id`, - e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, + if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, + 0 AS exclusion_0, + 0 AS exclusion_1, + 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1610,7 +1614,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + HAVING ifNull(greaterOrEquals(af, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1636,42 +1640,46 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS step_reached, - plus(af_tuple.1, 1) AS steps, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS af, af_tuple.2 AS breakdown, - af_tuple.3 AS timings, - aggregation_target AS aggregation_target + af_tuple.3 AS timings FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - uuid AS uuid, - `$session_id` AS `$session_id`, - `$window_id` AS `$window_id`, - step_0 AS step_0, - step_1 AS step_1, - step_2 AS step_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + step_2 AS step_2, + latest_2 AS latest_2, + exclusion_0 AS exclusion_0, + exclusion_1 AS exclusion_1, + exclusion_2 AS exclusion_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e.`$group_0` AS aggregation_target, - e.uuid AS uuid, - e.`$session_id` AS `$session_id`, - e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, + if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, + 0 AS exclusion_0, + 0 AS exclusion_1, + 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1686,7 +1694,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + HAVING ifNull(greaterOrEquals(af, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -1712,42 +1720,46 @@ groupArray(row_number) AS row_number, final_prop AS final_prop FROM - (SELECT countIf(ifNull(ifNull(equals(step_reached, 0), 0), 0)) AS step_1, - countIf(ifNull(ifNull(equals(step_reached, 1), 0), 0)) AS step_2, - countIf(ifNull(ifNull(equals(step_reached, 2), 0), 0)) AS step_3, + (SELECT countIf(ifNull(ifNull(equals(af, 0), 0), 0)) AS step_1, + countIf(ifNull(ifNull(equals(af, 1), 0), 0)) AS step_2, + countIf(ifNull(ifNull(equals(af, 2), 0), 0)) AS step_3, groupArrayIf(timings[1], ifNull(greater(timings[1], 0), 0)) AS step_1_conversion_times, groupArrayIf(timings[2], ifNull(greater(timings[2], 0), 0)) AS step_2_conversion_times, rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, - af_tuple.1 AS step_reached, - plus(af_tuple.1, 1) AS steps, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + af_tuple.1 AS af, af_tuple.2 AS breakdown, - af_tuple.3 AS timings, - aggregation_target AS aggregation_target + af_tuple.3 AS timings FROM (SELECT timestamp AS timestamp, aggregation_target AS aggregation_target, - uuid AS uuid, - `$session_id` AS `$session_id`, - `$window_id` AS `$window_id`, - step_0 AS step_0, - step_1 AS step_1, - step_2 AS step_2, - prop_basic AS prop_basic, - prop, - prop_vals AS prop_vals, - prop_vals AS prop + step_0 AS step_0, + latest_0 AS latest_0, + step_1 AS step_1, + latest_1 AS latest_1, + step_2 AS step_2, + latest_2 AS latest_2, + exclusion_0 AS exclusion_0, + exclusion_1 AS exclusion_1, + exclusion_2 AS exclusion_2, + prop_basic AS prop_basic, + prop, + prop_vals AS prop_vals, + prop_vals AS prop FROM (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS aggregation_target, - e.uuid AS uuid, - e.`$session_id` AS `$session_id`, - e.`$window_id` AS `$window_id`, if(equals(e.event, 'sign up'), 1, 0) AS step_0, + if(ifNull(equals(step_0, 1), 0), timestamp, NULL) AS latest_0, if(equals(e.event, 'play movie'), 1, 0) AS step_1, + if(ifNull(equals(step_1, 1), 0), timestamp, NULL) AS latest_1, if(equals(e.event, 'buy'), 1, 0) AS step_2, + if(ifNull(equals(step_2, 1), 0), timestamp, NULL) AS latest_2, + 0 AS exclusion_0, + 0 AS exclusion_1, + 0 AS exclusion_2, ifNull(toString(e__group_0.properties___industry), '') AS prop_basic, prop_basic AS prop, argMinIf(prop, timestamp, isNotNull(prop)) OVER (PARTITION BY aggregation_target) AS prop_vals @@ -1769,7 +1781,7 @@ groups.group_key) AS e__group_0 ON equals(e.`$group_0`, e__group_0.key) WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC')), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), toDateTime64('2020-01-08 23:59:59.999999', 6, 'UTC')))))) GROUP BY aggregation_target - HAVING ifNull(greaterOrEquals(step_reached, 0), 0)) + HAVING ifNull(greaterOrEquals(af, 0), 0)) GROUP BY breakdown ORDER BY step_3 DESC, step_2 DESC, step_1 DESC) GROUP BY final_prop @@ -2283,7 +2295,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2359,7 +2371,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2435,7 +2447,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr index 3bc57fc96fc6a..07c6a328a4d04 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr @@ -7,7 +7,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends_v1(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'UTC') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown @@ -52,7 +52,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends_v1(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'US/Pacific') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown @@ -97,7 +97,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends_v1(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfWeek(timestamp, 0), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfWeek(timestamp, 0), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'UTC') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr index 7d2c9dfd6e82d..7b910d2701701 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr @@ -19,7 +19,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -67,7 +67,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -143,7 +143,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -217,7 +217,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -278,7 +278,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -337,7 +337,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -404,7 +404,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -471,7 +471,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -553,7 +553,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -609,7 +609,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -662,7 +662,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -730,7 +730,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'step_1', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'step_1', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -805,7 +805,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array_v1(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -878,7 +878,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -954,7 +954,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1030,7 +1030,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_v1(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/queries/funnels/test/__snapshots__/test_funnel_time_to_convert.ambr b/posthog/queries/funnels/test/__snapshots__/test_funnel_time_to_convert.ambr index 6ccb7f1a035d0..3ccc12d354191 100644 --- a/posthog/queries/funnels/test/__snapshots__/test_funnel_time_to_convert.ambr +++ b/posthog/queries/funnels/test/__snapshots__/test_funnel_time_to_convert.ambr @@ -126,260 +126,6 @@ max_expanded_ast_elements=1000000 ''' # --- -# name: TestFunnelTimeToConvert.test_auto_bin_count_total - ''' - WITH step_runs AS - (SELECT aggregation_target, - steps, - avg(step_1_conversion_time) step_1_average_conversion_time_inner, - avg(step_2_conversion_time) step_2_average_conversion_time_inner, - median(step_1_conversion_time) step_1_median_conversion_time_inner, - median(step_2_conversion_time) step_2_median_conversion_time_inner - FROM - (SELECT aggregation_target, - steps, - max(steps) over (PARTITION BY aggregation_target) as max_steps, - step_1_conversion_time, - step_2_conversion_time - FROM - (SELECT *, - if(latest_0 <= latest_1 - AND latest_1 <= latest_0 + INTERVAL 7 DAY - AND latest_1 <= latest_2 - AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 - AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps , - if(isNotNull(latest_1) - AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, - if(isNotNull(latest_2) - AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - latest_1, - step_2, - min(latest_2) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_2 - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - latest_1, - step_2, - if(latest_2 < latest_1, NULL, latest_2) as latest_2 - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - min(latest_1) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_1, - step_2, - min(latest_2) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_2 - FROM - (SELECT e.timestamp as timestamp, - pdi.person_id as aggregation_target, - pdi.person_id as person_id, - if(event = 'step one', 1, 0) as step_0, - if(step_0 = 1, timestamp, null) as latest_0, - if(event = 'step two', 1, 0) as step_1, - if(step_1 = 1, timestamp, null) as latest_1, - if(event = 'step three', 1, 0) as step_2, - if(step_2 = 1, timestamp, null) as latest_2 - FROM events e - INNER JOIN - (SELECT distinct_id, - argMax(person_id, version) as person_id - FROM person_distinct_id2 - WHERE team_id = 2 - AND distinct_id IN - (SELECT distinct_id - FROM events - WHERE team_id = 2 - AND event IN ['step one', 'step three', 'step two'] - AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-06-07 00:00:00', 'UTC') - AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-06-13 23:59:59', 'UTC') ) - GROUP BY distinct_id - HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id - WHERE team_id = 2 - AND event IN ['step one', 'step three', 'step two'] - AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-06-07 00:00:00', 'UTC') - AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-06-13 23:59:59', 'UTC') - AND (step_0 = 1 - OR step_1 = 1 - OR step_2 = 1) )))) - WHERE step_0 = 1 )) - GROUP BY aggregation_target, - steps - HAVING steps = max_steps), - histogram_params AS - (SELECT ifNull(floor(min(step_1_average_conversion_time_inner + step_2_average_conversion_time_inner)), 0) AS from_seconds, - ifNull(ceil(max(step_1_average_conversion_time_inner + step_2_average_conversion_time_inner)), 1) AS to_seconds, - round(avg(step_1_average_conversion_time_inner + step_2_average_conversion_time_inner), 2) AS average_conversion_time, - count() AS sample_count, - least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, - ceil((to_seconds - from_seconds) / bin_count) AS bin_width_seconds_raw, - if(bin_width_seconds_raw > 0, bin_width_seconds_raw, 60) AS bin_width_seconds - FROM step_runs - WHERE step_2_average_conversion_time_inner IS NOT NULL ), - - (SELECT bin_width_seconds - FROM histogram_params) AS bin_width_seconds, - - (SELECT bin_count - FROM histogram_params) AS bin_count, - - (SELECT from_seconds - FROM histogram_params) AS histogram_from_seconds, - - (SELECT to_seconds - FROM histogram_params) AS histogram_to_seconds, - - (SELECT average_conversion_time - FROM histogram_params) AS histogram_average_conversion_time - SELECT bin_from_seconds, - person_count, - histogram_average_conversion_time AS average_conversion_time - FROM - (SELECT histogram_from_seconds + floor((step_1_average_conversion_time_inner + step_2_average_conversion_time_inner - histogram_from_seconds) / bin_width_seconds) * bin_width_seconds AS bin_from_seconds, - count() AS person_count - FROM step_runs - GROUP BY bin_from_seconds) results - RIGHT OUTER JOIN - (SELECT histogram_from_seconds + number * bin_width_seconds AS bin_from_seconds - FROM system.numbers - LIMIT ifNull(bin_count, 0) + 1) fill USING (bin_from_seconds) - ORDER BY bin_from_seconds SETTINGS max_ast_elements=1000000, - max_expanded_ast_elements=1000000 - ''' -# --- -# name: TestFunnelTimeToConvert.test_auto_bin_count_total.1 - ''' - WITH step_runs AS - (SELECT aggregation_target, - steps, - avg(step_1_conversion_time) step_1_average_conversion_time_inner, - avg(step_2_conversion_time) step_2_average_conversion_time_inner, - median(step_1_conversion_time) step_1_median_conversion_time_inner, - median(step_2_conversion_time) step_2_median_conversion_time_inner - FROM - (SELECT aggregation_target, - steps, - max(steps) over (PARTITION BY aggregation_target) as max_steps, - step_1_conversion_time, - step_2_conversion_time - FROM - (SELECT *, - if(latest_0 <= latest_1 - AND latest_1 <= latest_0 + INTERVAL 7 DAY - AND latest_1 <= latest_2 - AND latest_2 <= latest_0 + INTERVAL 7 DAY, 3, if(latest_0 <= latest_1 - AND latest_1 <= latest_0 + INTERVAL 7 DAY, 2, 1)) AS steps , - if(isNotNull(latest_1) - AND latest_1 <= latest_0 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time, - if(isNotNull(latest_2) - AND latest_2 <= latest_1 + INTERVAL 7 DAY, dateDiff('second', toDateTime(latest_1), toDateTime(latest_2)), NULL) step_2_conversion_time - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - latest_1, - step_2, - min(latest_2) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_2 - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - latest_1, - step_2, - if(latest_2 < latest_1, NULL, latest_2) as latest_2 - FROM - (SELECT aggregation_target, timestamp, step_0, - latest_0, - step_1, - min(latest_1) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_1, - step_2, - min(latest_2) over (PARTITION by aggregation_target - ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_2 - FROM - (SELECT e.timestamp as timestamp, - pdi.person_id as aggregation_target, - pdi.person_id as person_id, - if(event = 'step one', 1, 0) as step_0, - if(step_0 = 1, timestamp, null) as latest_0, - if(event = 'step two', 1, 0) as step_1, - if(step_1 = 1, timestamp, null) as latest_1, - if(event = 'step three', 1, 0) as step_2, - if(step_2 = 1, timestamp, null) as latest_2 - FROM events e - INNER JOIN - (SELECT distinct_id, - argMax(person_id, version) as person_id - FROM person_distinct_id2 - WHERE team_id = 2 - AND distinct_id IN - (SELECT distinct_id - FROM events - WHERE team_id = 2 - AND event IN ['step one', 'step three', 'step two'] - AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-06-07 00:00:00', 'UTC') - AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-06-13 23:59:59', 'UTC') ) - GROUP BY distinct_id - HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id - WHERE team_id = 2 - AND event IN ['step one', 'step three', 'step two'] - AND toTimeZone(timestamp, 'UTC') >= toDateTime('2021-06-07 00:00:00', 'UTC') - AND toTimeZone(timestamp, 'UTC') <= toDateTime('2021-06-13 23:59:59', 'UTC') - AND (step_0 = 1 - OR step_1 = 1 - OR step_2 = 1) )))) - WHERE step_0 = 1 )) - GROUP BY aggregation_target, - steps - HAVING steps = max_steps), - histogram_params AS - (SELECT ifNull(floor(min(step_1_average_conversion_time_inner + step_2_average_conversion_time_inner)), 0) AS from_seconds, - ifNull(ceil(max(step_1_average_conversion_time_inner + step_2_average_conversion_time_inner)), 1) AS to_seconds, - round(avg(step_1_average_conversion_time_inner + step_2_average_conversion_time_inner), 2) AS average_conversion_time, - count() AS sample_count, - least(60, greatest(1, ceil(cbrt(ifNull(sample_count, 0))))) AS bin_count, - ceil((to_seconds - from_seconds) / bin_count) AS bin_width_seconds_raw, - if(bin_width_seconds_raw > 0, bin_width_seconds_raw, 60) AS bin_width_seconds - FROM step_runs - WHERE step_2_average_conversion_time_inner IS NOT NULL ), - - (SELECT bin_width_seconds - FROM histogram_params) AS bin_width_seconds, - - (SELECT bin_count - FROM histogram_params) AS bin_count, - - (SELECT from_seconds - FROM histogram_params) AS histogram_from_seconds, - - (SELECT to_seconds - FROM histogram_params) AS histogram_to_seconds, - - (SELECT average_conversion_time - FROM histogram_params) AS histogram_average_conversion_time - SELECT bin_from_seconds, - person_count, - histogram_average_conversion_time AS average_conversion_time - FROM - (SELECT histogram_from_seconds + floor((step_1_average_conversion_time_inner + step_2_average_conversion_time_inner - histogram_from_seconds) / bin_width_seconds) * bin_width_seconds AS bin_from_seconds, - count() AS person_count - FROM step_runs - GROUP BY bin_from_seconds) results - RIGHT OUTER JOIN - (SELECT histogram_from_seconds + number * bin_width_seconds AS bin_from_seconds - FROM system.numbers - LIMIT ifNull(bin_count, 0) + 1) fill USING (bin_from_seconds) - ORDER BY bin_from_seconds SETTINGS max_ast_elements=1000000, - max_expanded_ast_elements=1000000 - ''' -# --- # name: TestFunnelTimeToConvert.test_basic_strict ''' WITH step_runs AS diff --git a/posthog/test/user_scripts/test_aggregate_funnel.py b/posthog/test/user_scripts/test_aggregate_funnel.py deleted file mode 100644 index f1fe254886c49..0000000000000 --- a/posthog/test/user_scripts/test_aggregate_funnel.py +++ /dev/null @@ -1,4259 +0,0 @@ -import io -from contextlib import redirect_stdout -from typing import Any - -from posthog.user_scripts.aggregate_funnel import calculate_funnel_from_user_events - - -def test(): - y = [ - [(1577973600.0, "uuid", "", [1]), (1577980800.0, "uuid", "", [2]), (1577984400.0, "uuid", "", [3])], - [(1577880000.0, "uuid", "", [1]), (1577883600.0, "uuid", "", [2]), (1577890800.0, "uuid", "", [3])], - [(1577973600.0, "uuid", "", [1]), (1577980800.0, "uuid", "", [2])], - ] - - for x in y: - calculate_funnel_from_user_events(3, 1209600, "first_touch", "strict", [""], x) - - -def test2(): - a: list[Any] = [ - [(1720051532.484019, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720105713.331995, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720329565.847159, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720186008.567886, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326697.522923, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482974.426314, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720327526.250804, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720497558.23414, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719979738.339271, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720025384.961105, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504618.55439, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720136408.619257, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136458.666712, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136460.776795, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136463.761667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136465.813823, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153490.167176, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153611.687424, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153613.813758, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221238.819741, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221389.412602, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720234125.717526, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720245095.229565, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396821.910578, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502554.801179, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720237286.585886, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492842.0014, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720145259.463577, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720173037.951133, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720398629.834351, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720576515.470242, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720488634.248776, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719966672.507604, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720379305.230415, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485725.30467, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720056848.984567, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234634.97164, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326372.083307, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487169.130815, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719979630.05111, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720067082.599895, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720065455.678956, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720141594.235645, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720479638.868071, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720172558.775714, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589944.987293, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720240665.403432, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720403456.771406, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720151433.593775, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397705.729741, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407937.654196, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720063019.413544, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230670.007217, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572529.432945, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720062676.566511, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062768.411832, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062770.476807, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062771.394614, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156065.434007, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156180.339675, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720053274.311851, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574916.370766, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720403600.103166, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720070524.509752, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720330735.128105, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719980823.099161, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720109783.667678, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488536.75761, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720120539.020908, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235556.263511, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404531.8727, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720461710.602542, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720142147.27027, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720463509.177443, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720609249.094945, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720061653.09558, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331923.364924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493879.336969, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719981455.944035, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719981517.705732, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994503.81365, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994621.6397, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994623.698368, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994627.578717, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994629.663136, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994631.068061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719994633.142381, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720027463.767433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720027502.563106, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720027504.670674, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057341.723675, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057343.781939, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720145087.601179, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720145089.680587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243008.749524, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243068.439551, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318425.097956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318427.16319, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318432.221956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318434.329525, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418148.778433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418150.861104, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488202.399436, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488212.260625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488214.365566, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572393.815712, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720613041.916708, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720057097.342555, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317039.904735, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720483178.967836, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720181661.187285, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720199552.174104, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568803.062761, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720247391.136136, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410696.088339, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720599399.171422, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720312357.61565, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720052008.103911, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720400141.042944, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720210751.331903, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720503558.839248, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720241352.747626, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321677.766712, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720409706.122052, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720519728.980875, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977467.931514, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568695.132969, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720071302.148667, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238096.092618, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720057437.769059, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720221473.506037, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720348129.55283, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482938.000889, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576755.035308, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720235902.362301, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720024782.723245, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720070158.75827, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720000651.858702, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720244645.395695, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411107.259775, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720191076.938109, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720322967.081356, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323158.146239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323172.234517, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323206.302768, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323313.146535, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323364.511129, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323458.282407, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720065260.493236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720065334.608797, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141650.234015, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141749.547675, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141751.641012, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154278.705276, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154280.760532, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229499.077048, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229572.436301, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720259010.216367, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720259234.335094, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720259236.42606, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318686.64822, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318843.45613, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318845.509738, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720363113.918907, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720363184.856665, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400947.604003, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400949.633637, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498232.720406, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498253.802808, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498255.908508, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586991.26782, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720587059.251675, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720587061.383312, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720638042.876812, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720638133.182092, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720638135.286491, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978486.488845, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720406010.994165, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720062931.526777, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720142330.725196, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238332.287607, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404745.279674, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577388.350881, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719973721.653682, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720045556.714061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720286335.062706, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720408637.593505, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719980831.540691, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980890.3872, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980892.464391, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720027957.165729, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720027959.212697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055928.682589, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055930.747743, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138782.333308, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138842.547168, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138844.667335, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138846.225705, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153595.409537, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153694.792152, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222583.234486, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222651.732326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222653.840022, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231129.338916, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231262.508465, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315761.130281, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315844.746953, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315846.831435, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406873.849957, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406879.412626, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485467.197531, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485486.733099, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485488.847143, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485492.354688, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485494.434006, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581292.87898, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581372.990683, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965396.997192, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720109840.37035, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720224849.338664, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311680.960628, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720593841.069028, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720193711.631887, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720355386.424798, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720137394.637585, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720227526.549035, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720601724.604091, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720242114.286726, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720495287.866943, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984060.976083, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233353.478142, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331822.027661, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499420.953642, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720327908.649598, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720327957.004146, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328002.921775, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328054.34555, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394578.210396, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394668.213374, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394670.323029, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410358.68385, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410430.047079, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410432.093006, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485479.982584, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485552.035405, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485554.099771, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576265.461408, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576267.553332, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580196.882833, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580198.938581, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580201.66793, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580203.765767, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720512918.56325, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720587573.354151, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720059581.380866, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226059.821101, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569936.860231, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720483812.243251, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720047890.599986, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720151933.610926, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720426395.237753, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589584.479646, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720050613.849179, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720183728.480776, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720245305.222942, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974717.393306, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238913.058213, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720403863.202175, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720066616.245506, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720329802.077257, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720058023.220462, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720273250.296181, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720400521.741834, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720590006.799829, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719977522.311193, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394307.490994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720541599.758133, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720059720.64277, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720225557.277258, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318879.528985, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720448939.738279, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720159019.782951, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232688.231366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312031.934367, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720420263.292336, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720051467.327131, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226107.259649, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410027.350582, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719966308.30787, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136775.382126, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720453167.302523, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578911.142536, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965705.478301, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720089492.274268, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720458943.365803, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588170.374851, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720137202.259506, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309242.730837, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720397209.557207, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720628958.303298, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719967303.936898, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720069496.922345, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719970996.586184, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720168525.715398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504098.515479, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720601826.09111, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719971199.057468, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068258.0151, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137337.044491, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719971421.175757, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720134959.956933, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719976305.13246, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720059646.658845, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720145964.773181, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233116.664838, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720436748.603567, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719969550.144929, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720315269.690666, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720274096.315691, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720274154.981534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720274184.028094, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720268306.026574, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720323182.163554, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720032173.053995, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720157155.365383, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314424.94755, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481047.114281, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720010572.095008, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968638.302149, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968762.98274, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968765.072701, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720005012.137582, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720005160.858454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720005162.913788, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720175681.69546, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720175774.033356, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720175776.151125, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720220252.732147, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720220252.777516, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720220256.747294, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492139.162569, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492141.256483, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719970987.569565, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720054508.915859, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720315224.08896, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720325854.156535, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720483854.080251, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720406510.418443, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720030600.544521, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720069524.719771, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484112.369653, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568851.121099, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720304785.385271, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720313035.494802, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313090.718424, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313239.783577, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313343.042083, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404935.491204, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404979.552845, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404981.647182, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501716.284759, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501761.154088, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501763.234903, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584650.853158, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584688.899508, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584691.020015, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720229088.205557, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720487228.612214, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720241088.456982, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720042764.160666, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984325.782697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720047953.098659, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720268267.887048, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720054622.362154, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134575.953204, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416355.096939, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500581.691615, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719972690.486054, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972877.103609, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972879.22778, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972881.797102, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972883.859612, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052338.317127, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052340.409592, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720069426.554888, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720069428.615973, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149027.365317, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149089.951754, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149092.012724, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234565.610403, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239125.82035, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239147.87241, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318243.573983, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318245.63705, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418009.877203, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418011.983148, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418014.464823, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485277.913378, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485280.026695, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574328.529507, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574330.633898, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581736.051228, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581766.135021, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581768.228326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652888.715284, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720328167.133332, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394291.998224, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720138278.025347, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720411684.615562, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719979551.790599, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062548.79153, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152645.092565, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720273648.542968, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720150050.836492, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720235665.517364, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720504709.666893, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720502409.011067, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652305.691241, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719983664.396995, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057964.860551, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720058069.016671, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720119055.986377, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720119177.882926, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720146988.862958, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720146990.940118, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720207091.824328, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720207147.984162, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720207150.045311, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221686.916464, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221731.792885, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221733.892091, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221736.114027, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221738.1731, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221740.137735, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221742.219472, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319188.083254, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319190.195166, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333160.336537, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333162.39224, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350382.882768, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350384.998862, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350385.400746, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350387.504804, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350390.868713, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350392.929211, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482928.905461, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482987.630373, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720549510.694147, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720549582.87966, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720549584.95341, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581476.586746, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581478.656771, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977177.729628, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720393638.078415, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719980378.113974, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720443102.049493, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590770.939412, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719979883.308045, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230654.923495, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310908.910099, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719964829.898192, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719964832.003811, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985240.876339, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985242.911416, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985243.633507, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985245.665729, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060650.829248, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060759.718692, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060761.830242, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070260.443094, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070280.911994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070282.979246, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134645.425223, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134793.819981, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134795.932398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155938.192604, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155940.320279, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155945.041101, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155947.088061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236895.111761, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236912.473535, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236914.593968, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236917.655587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318871.824625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318935.358285, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318937.446561, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318940.05207, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318942.106239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405217.370251, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405312.528519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405314.627163, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413100.204244, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413102.291035, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496542.308228, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574260.260325, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574343.117651, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574345.20748, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578705.104516, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578717.159504, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578719.26077, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720071370.538676, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719972220.86175, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720227223.558904, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720047692.206123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720074479.043983, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221755.131247, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720343377.429715, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581159.65796, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720054906.379171, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326827.193456, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395837.565662, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719972411.855532, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972538.863121, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972540.935712, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063717.900878, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063719.954111, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070114.807467, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070235.024434, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070237.14674, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720097819.236115, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720097978.260021, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720097980.382821, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720151026.716063, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720151173.670938, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720151175.717239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720166439.941955, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720166583.693905, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720166585.791065, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720181553.630642, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720181555.746202, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242210.300006, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242331.451228, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720316730.127117, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720316751.481651, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350332.517593, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350427.724851, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350429.836812, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396153.382808, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396199.106453, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396201.15929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720424092.525755, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720424190.959176, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720424193.037739, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492456.877253, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492529.103048, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492531.198928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720583806.008143, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720583868.43082, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720648763.855471, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720648878.799852, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720648880.882297, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720071793.774403, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309002.505766, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720367384.379119, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978345.677095, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720134660.416426, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720056400.339178, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137451.906538, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581731.115191, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719974999.631834, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720503857.499785, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720325249.830373, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719970175.486046, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061532.244847, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720387059.054565, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720157797.242967, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720490173.84352, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720568387.145132, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720027447.264569, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719979106.899872, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720417473.653713, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720153359.982848, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720468837.459019, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720047669.218866, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720230050.113895, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719975411.228945, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235199.496284, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720403154.17646, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720626578.282517, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978136.275137, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720331670.572264, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719975669.597909, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719975763.25366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055306.937976, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055449.351479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067433.572041, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067452.84519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067454.935816, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233716.974937, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233884.056907, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233886.107033, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238869.144339, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239054.729577, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239056.811577, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720248048.594017, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720248147.506317, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720248149.540209, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323761.342714, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323763.381547, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400825.240853, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400844.815642, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410954.1329, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410956.230411, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410956.661655, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410958.800282, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414005.128157, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414035.742095, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414037.861356, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414039.522054, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414041.622559, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449836.553695, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449909.88067, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449912.006572, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504478.640048, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504584.183246, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504586.273448, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589586.941948, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589732.653657, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589734.757411, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589735.718174, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719987925.192586, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720319498.157106, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720140316.935341, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720581286.138288, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984942.453601, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720334036.972544, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568302.136228, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720231990.896895, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320392.727402, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720151072.246138, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309428.675922, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720652752.302257, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719977332.758786, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720135118.942837, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498977.766189, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720054300.10225, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720419250.119038, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720170242.586928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720322954.401713, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500416.057333, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719976447.157218, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720134454.623643, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720482790.529945, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720575291.374898, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720575147.912954, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719997197.65312, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137704.47896, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226085.527498, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720306837.86921, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720314781.298338, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720443503.319112, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719976515.23989, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720225806.720086, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720388901.256231, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720490185.842396, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720568142.650151, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720587602.828532, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720228569.783763, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720577136.698764, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720058398.793045, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317616.711315, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498994.241943, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719988512.009335, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411879.880695, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575546.218164, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720245099.046699, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652539.847041, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719965518.303227, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720241249.736668, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410560.906617, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566388.427971, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720033619.669265, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309514.690673, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584737.484501, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719981137.891986, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719981255.525287, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719981257.57542, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156254.934266, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156432.088183, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221245.352908, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221247.415618, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720306695.430622, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720306697.509606, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720399726.625066, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720399728.675873, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486842.405361, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486974.649877, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720494605.919949, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720494724.480053, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720494726.541559, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572824.284783, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572826.355789, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652512.753893, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652514.833743, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720044224.653908, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720583176.852571, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720567262.122889, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720518049.925836, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720148280.678113, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720391739.484219, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719983654.268169, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983761.844014, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983763.902973, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720014262.846562, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720014264.966534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720014268.064236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720014270.176366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062164.847608, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062166.93557, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070760.286042, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070793.879274, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070795.974998, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136175.682667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136177.782735, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150756.421019, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150758.537073, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226712.358545, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320316.371588, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396676.623722, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396759.330429, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482810.511366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482891.609285, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482893.739553, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502988.652815, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503034.447086, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503036.52898, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503036.606516, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503038.712119, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566567.148583, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566710.618717, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624425.022175, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624567.571474, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624569.66289, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652508.525789, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978793.297818, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312690.624643, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720408103.17786, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720496665.901316, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720397084.267673, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720499411.209847, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720111853.777887, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720111923.412934, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139482.167685, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139533.842338, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139535.907287, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139540.267313, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139542.34773, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139547.051966, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139549.136732, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720464344.794745, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720464401.900918, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720464404.029255, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498850.875209, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499103.608103, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719973523.458065, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720233566.787523, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720407928.090004, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720032729.148346, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720062532.225999, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720034095.862663, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720491285.681862, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720096472.997597, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568056.766425, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720138718.911672, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720336998.597537, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489473.142035, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574315.596422, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720577328.151149, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720072713.69671, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720231002.690818, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719966317.997493, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238108.647106, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720146847.656681, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720239981.42926, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720081339.444776, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720234051.371763, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720236937.844197, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720501314.981075, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720495611.198831, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720071452.84595, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720320971.754361, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982790.224924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982861.078823, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982863.122702, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052453.241504, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052505.408448, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052507.485592, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720078456.868981, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137047.584706, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137124.096958, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137126.192241, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155528.420602, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155596.835697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155598.919376, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720204090.330488, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720204222.690243, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720204224.805824, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232760.467367, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232859.977733, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242903.930897, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242906.021355, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309697.411345, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309699.483954, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406346.354509, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406523.466919, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406525.535072, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720065979.154591, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720325699.423285, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720244750.093352, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394343.192185, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720193298.590097, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720315677.193089, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720501281.07252, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720055721.622214, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720137839.895581, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231251.548774, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720350224.693877, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720519304.741337, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586487.784295, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719969181.053709, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720434586.266895, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720070912.148493, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720244703.673132, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720494833.034907, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720053732.993216, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053735.086697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720081490.114819, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720081492.188923, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720108329.744396, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720108420.858541, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720108422.93886, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142971.786605, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143021.896153, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149975.921352, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150041.125351, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150043.15518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720200733.408027, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720200744.366236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720200746.48024, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226248.428928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226387.261389, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325189.273212, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720367266.448359, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720367268.528501, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397514.119584, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397583.541623, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397585.62972, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407649.068004, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407859.450723, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407861.5267, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418226.184583, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418312.907521, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418312.959891, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418314.508588, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720429033.410454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720429217.5183, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720429219.58254, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720476196.299215, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720476290.414317, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720476292.497993, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496668.635514, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496670.762669, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566807.578929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566881.524889, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566883.613068, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575742.398153, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575760.407369, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575762.530879, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720623060.799492, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720623163.775703, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720623165.819144, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720490829.088908, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720222040.449568, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328183.580613, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581997.108309, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720631726.024509, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719969186.42388, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236467.453142, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720460294.599805, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720328624.599959, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411036.02508, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720470233.314202, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719966062.758672, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057471.705526, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325034.717518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407309.902625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573477.911506, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720063887.70449, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720343326.152899, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720411362.644921, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720395606.751317, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720155980.858558, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720450339.669296, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719981567.460091, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720587320.169523, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720245122.915738, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719970229.063219, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720488361.805483, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720320009.047059, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720139484.708505, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720396780.73649, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720238094.386701, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720627574.598265, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720136834.089355, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720396824.609765, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720225652.369657, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982133.012616, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982177.631804, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982179.720602, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720006591.274361, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720006644.930183, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720006647.03435, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720460548.964008, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720460614.237345, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720460616.332418, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585282.645498, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585293.462072, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720370572.550118, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719973160.879923, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720329101.982409, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581501.430356, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720063998.039445, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232764.384684, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502473.633051, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720153647.635598, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720225923.85076, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413430.570698, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584131.042756, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719966759.043742, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720405936.570297, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720144919.519677, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720402676.1685, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720402994.034134, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720497341.728864, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719973785.927392, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142506.754009, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312482.395361, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578049.42885, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720143203.796648, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720504600.034248, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720138317.024564, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720307922.860078, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720576710.045341, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720237948.24219, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720322691.233406, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412663.957815, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720342019.617667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720342090.227667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720342263.731169, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720342307.569989, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720342413.538738, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720342570.868506, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720342664.423143, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720053725.982337, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137089.95596, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720250340.159455, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720408080.82431, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720502215.54816, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720051018.757074, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720221304.68857, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720055639.220711, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242136.136068, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501308.452889, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720210019.832882, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720222496.41532, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720221892.596089, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720488555.303827, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720055240.779901, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485059.84637, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720520102.630634, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720591031.4354, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720570592.888394, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720059956.606064, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232781.82764, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489307.963369, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720466563.789269, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720120332.505828, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720501386.247192, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720045443.968104, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720337612.000658, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484793.823359, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720240516.409323, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720508486.303913, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720056682.445295, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239570.480365, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720399243.691516, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720065346.577694, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720111179.563476, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152182.18393, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720456368.150945, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720037842.027886, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720051512.155726, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720316085.436368, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720153922.872643, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720316484.292604, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481626.562697, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720304528.044157, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720587171.914424, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719969690.052003, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720098093.259497, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589467.401983, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720182994.851728, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720490206.204252, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720305269.133214, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720580679.401674, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720582113.001824, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719971867.373391, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719971869.452767, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983561.418747, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983615.306689, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983617.371374, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983622.154397, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719983624.239597, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057585.854293, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720127843.991043, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720127952.545227, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150451.197164, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150472.889245, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229579.372015, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229585.29839, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229587.33746, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720272362.151724, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720272395.494166, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720272397.584197, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325287.360716, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325289.430457, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720392144.674955, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720392146.786158, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406690.885685, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406692.950513, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486441.134231, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486443.192435, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720648828.296221, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720648830.340132, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977053.236432, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720146886.388756, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720147721.983335, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720577319.095652, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720187232.833461, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720309745.334443, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720525020.981442, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719985270.896874, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720147203.361104, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719975189.590595, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720153681.561666, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315141.854012, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720483759.06017, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720632532.362134, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719969377.021113, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719969547.865829, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720050670.589639, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720050713.412665, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139076.150907, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139087.933212, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139090.022598, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139092.090332, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148904.698605, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720197454.202625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720197456.301898, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221957.937687, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222151.210074, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222153.281944, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231319.785278, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314287.823226, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314375.707773, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314377.787834, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331369.745063, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331582.949466, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331585.058912, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720399235.526545, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720399237.6268, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410762.341061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410808.990309, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410811.040448, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493330.828194, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493516.887173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501442.580123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501548.316894, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501550.379738, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573012.279738, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573204.24471, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573206.359087, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573210.996145, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573213.096745, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719984464.146305, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719969484.575186, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719967098.321792, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720140304.171738, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720067679.407113, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720240007.297001, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499615.946055, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719984745.989291, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720088802.060799, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226330.102201, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720057325.702019, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720499465.567145, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720055478.668518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055619.422527, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138025.392906, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138074.32289, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232045.90559, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232073.337701, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278094.793407, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278096.912409, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278099.569789, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278101.660519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720324663.973123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720324666.034118, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412864.0991, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412932.896312, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412934.95735, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493768.204791, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493848.668367, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493850.800293, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493853.855696, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578407.565863, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578455.012928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578457.12311, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720592507.954368, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720592695.674207, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720592697.763035, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720448820.538088, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720448848.354821, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720448968.980221, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449109.647373, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449132.605916, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449141.226924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720449174.132961, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720143295.563285, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720009875.184202, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720064301.403426, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221459.433168, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720316122.630709, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720625396.811387, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720064525.079458, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720600790.059805, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720053513.239524, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720533559.490134, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720222657.803241, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719971419.792625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239049.653382, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497253.487835, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571009.60795, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719978213.57048, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719978402.543586, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067921.564313, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068031.2973, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068033.364045, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720076693.193638, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720076695.234922, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720088372.082518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720088448.747115, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222636.476764, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222701.214913, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311136.481341, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311279.356667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311281.435353, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321937.516249, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321977.750869, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321979.826956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321983.309368, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417820.177018, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417888.907443, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482544.485269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482650.874077, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571012.586842, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571014.653099, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720067135.000485, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226886.323383, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720626810.190995, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720021468.494681, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720244311.296556, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720054497.052088, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315797.04068, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396623.976121, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719970439.050635, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720411294.606462, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720047660.240807, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720209425.126479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417042.301423, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720579466.836909, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720068666.058135, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720224717.712974, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313644.184984, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417247.572309, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720217112.012918, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720228893.793094, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719965114.583168, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221700.128257, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720359492.65181, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720149938.452021, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150083.518978, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150100.711862, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720403516.136956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720403602.399166, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720403688.061721, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720016151.530651, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720126052.51206, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243360.967974, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567481.805169, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720259903.388453, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720495071.607118, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719978731.351246, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142275.008236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720225627.748133, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720599835.060544, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720308817.017884, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720500376.721695, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720062080.162523, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720424051.051867, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577193.657241, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720226358.301934, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720611516.599998, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720142831.087971, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568727.59182, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720045127.801767, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720598254.557545, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720230498.737196, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720502519.921733, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720149819.132452, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720317818.669453, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719965630.184525, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720566194.006106, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719996710.23806, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720053587.04154, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720476400.319672, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720238998.499612, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720049964.339669, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720503256.459045, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720629914.75266, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720067406.552276, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720192823.078475, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720615636.068682, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720050726.320669, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720159164.117987, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720583837.972687, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720470505.483407, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589293.330858, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719990309.924021, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242385.881249, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720648573.041044, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720059240.88106, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720486550.385795, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720232277.114726, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720156360.413945, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720415380.907597, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720143721.130937, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720093040.94431, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720230385.831757, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720313919.101562, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720600894.542752, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720008883.059792, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720151981.800615, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720583883.771582, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720054595.476172, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720494101.96425, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719975987.869421, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072012.445937, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141541.892965, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974700.775073, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719974810.784479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720022010.687673, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720022125.15125, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720022127.183082, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720022127.850327, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720022129.972437, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149346.519881, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149423.39517, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232515.945385, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232642.031851, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232644.151326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232649.102724, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232651.213687, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720291284.378849, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720291307.651917, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317724.65539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317962.176994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317962.221761, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317967.870483, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416284.403485, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416286.45094, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720446964.44037, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720447111.491786, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720447113.551591, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500857.609857, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500933.241251, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500935.342693, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720550391.631024, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720550393.677097, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571962.115275, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571964.156322, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720300973.659698, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720502088.420309, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720226060.114355, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720367668.242413, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580879.469873, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720148122.993839, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720283848.988921, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720392902.670008, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720547569.939146, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720164561.277691, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720322322.293618, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720394391.029382, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720578227.91725, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720427348.104988, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720586312.438776, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719967279.972433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719967282.055508, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719986090.097845, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719986173.00659, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719986175.082864, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720034526.875582, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061201.725715, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061294.240057, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061296.35589, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155141.396653, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155143.510508, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155145.301155, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155147.393972, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231098.024705, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231317.54759, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720231319.611985, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720271983.621164, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720271985.710974, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720316981.40392, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317019.941522, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317022.040965, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411936.226228, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411963.208146, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720479757.589657, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720479839.302922, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720582109.835415, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720582111.914294, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652093.707438, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652211.598303, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720579951.356488, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720593973.655643, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720061475.003195, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720270392.101123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415797.057544, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574029.592383, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719987865.032004, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720212776.214811, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720315089.869542, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720578088.622431, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720575422.335555, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720329438.482756, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720443842.432414, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720135846.308239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221161.535587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326226.738859, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719977789.721113, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719977899.031956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719977901.119465, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982587.985388, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982666.211377, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982668.29279, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982672.56956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063592.708606, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063594.776009, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720145103.906614, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720145165.665926, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720157026.459569, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223512.011646, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223586.453989, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223588.535794, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720329405.565358, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720398313.307695, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720398429.724071, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414381.775047, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720446240.471098, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481889.793923, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481891.93036, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489136.015971, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489247.728734, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720318482.752639, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720242162.48487, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503535.294123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590538.582039, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720148407.104121, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720154168.367205, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568213.544423, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720069001.717509, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720346135.538471, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489854.284499, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719967260.706099, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720082538.484733, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720240732.567635, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395713.187024, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719968640.279026, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720058387.048155, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720240163.514327, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720391336.792179, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720310285.653948, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589147.207321, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719973140.021275, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720504055.006021, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720115792.85023, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720140689.444004, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312169.980048, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720399894.527727, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720316227.642169, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720484121.740556, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720150629.632571, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312593.72112, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584121.246833, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719966806.196729, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492831.262792, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720069584.25825, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233172.76065, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317363.164219, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720227600.733956, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227600.784387, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227605.27419, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720269710.791405, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720269759.332462, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326344.424672, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720369614.287387, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720369719.27491, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720369719.331218, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720369721.899004, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720385493.685201, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720385551.219825, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720385553.316418, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720450115.39061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720450117.502598, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720450118.78177, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719969800.978378, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222415.35262, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720434706.74629, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720237451.24597, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720585495.150654, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719970937.04025, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719983075.420902, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313367.078665, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413122.113225, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720155749.238687, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720491353.243799, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720060021.000595, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719988378.536367, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720228662.183092, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719981886.782157, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720156878.496962, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720582313.689559, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720232302.477057, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720493756.958556, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720295778.241704, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720021503.203052, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720325452.491454, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720527219.478404, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567646.306507, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720223792.29193, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720006636.772706, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720006795.60427, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720006845.799981, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720007022.741945, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720007095.581047, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720007134.850115, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720025117.762503, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720025308.512649, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720025310.568037, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052547.163003, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052600.03312, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068046.902248, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068213.189912, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720144711.311281, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720144713.407177, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222638.332245, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222640.418838, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242141.813366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242245.921587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242248.011768, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333146.03005, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333287.562561, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333289.592652, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333292.319879, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720333294.386109, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396984.211837, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397094.401782, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486134.144443, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486136.211044, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486140.873481, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486142.970428, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497754.706526, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497979.155047, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720531991.462042, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720532199.030662, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588796.771517, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588842.077879, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588844.116306, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720239926.764196, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720395045.1902, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720431147.297621, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720240748.713179, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719972432.742571, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720410198.607466, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720566548.549011, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720455428.865155, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720498325.755933, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719983684.033908, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319741.991515, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414800.645761, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484979.12583, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720134283.600008, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720409485.01654, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719981074.661088, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143880.41593, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229983.175788, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060903.203334, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968419.743912, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968490.438903, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968620.857174, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498112.351156, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498358.36836, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498468.250047, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574778.111823, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574806.5479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574917.425735, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574933.603291, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575020.164914, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720406407.483318, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720412099.352018, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720498223.084881, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719979024.598321, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720114791.984992, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720241390.157269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500283.345509, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720569522.382331, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720146840.111051, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720287268.372643, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720583508.926048, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720229146.528014, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229340.131801, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229424.480475, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229565.859999, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229567.783491, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229693.297904, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720229755.453165, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720098291.146186, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719983104.788269, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720070626.816099, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720226820.995006, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720316639.892049, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589368.875624, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720070877.576019, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720234703.959519, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719978870.060134, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137971.413991, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491059.303159, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719995043.481796, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720148819.805573, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720052005.359573, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052127.565063, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052129.679258, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720064915.795875, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720064917.840723, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720064919.250429, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720140563.359858, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720140686.221967, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147133.126896, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154606.237768, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720208312.107821, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720208397.77235, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720208399.88578, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226692.740751, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226809.874422, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226811.929607, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320735.680282, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320737.781583, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394544.101953, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394546.228449, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411628.159882, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411765.678009, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411765.737071, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411771.063593, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493021.815332, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493023.89141, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720547092.818141, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720547133.337079, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566405.934125, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566407.979963, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720592934.864349, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720407281.391395, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720578489.911262, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720393905.799101, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719965431.440319, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719965547.770505, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719965549.880668, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720010279.644796, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720010481.117481, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060297.061777, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060299.106745, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072795.790373, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072933.175213, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138923.382269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138952.892452, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138954.952138, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243737.055635, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243742.725476, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243744.812736, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278868.092914, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278981.120539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720278983.221413, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312851.319112, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312961.59678, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312963.701002, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401167.589016, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401192.232905, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488671.153932, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488673.262556, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498148.914747, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498151.01221, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585902.00157, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585904.068243, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720627230.183177, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720627251.343451, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720627253.395817, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720049050.269443, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720406587.77676, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720201120.604139, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237348.670203, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503188.882528, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720137961.069782, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720233994.333193, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720148673.115174, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720017472.013793, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238395.438066, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481118.520931, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624077.141735, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720460985.277631, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720065960.10824, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568092.250721, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719964803.220143, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720072690.78503, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719973118.028284, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720148963.270876, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720055800.056897, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147428.656208, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237025.123131, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326902.440989, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719967443.988967, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719967507.96168, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719967510.01003, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719967510.547419, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719967512.630086, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138300.130825, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138300.228601, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138302.137449, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720266243.760636, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720266262.29505, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720266262.382243, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720266267.714044, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720376066.44502, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720376075.005446, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720376075.055395, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720376078.271297, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720495615.317205, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720495625.121167, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720495627.190587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720495631.668389, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720094115.933922, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720327035.126978, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652576.382878, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720494001.577927, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720102356.301353, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720244955.2084, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393949.41044, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576986.579566, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720033048.609785, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720402968.773862, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720230211.716966, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720059787.289306, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397378.208597, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481196.422422, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720003149.057462, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720003372.883061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720003374.955179, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720039541.861276, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720039688.427965, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720039690.485555, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720048625.116329, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720048725.117697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141659.610639, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141661.665952, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720196426.042225, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720196487.09087, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720196489.183893, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720207066.952798, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720207237.857105, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720207239.919375, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720271033.503072, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720271035.587795, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720583123.471438, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720583125.576798, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720154856.626343, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226072.346309, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310601.449016, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720242303.35601, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720078404.748142, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720147584.809447, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720178488.289574, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720306985.894457, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720146748.830901, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720406666.368212, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720023013.684634, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720091577.184398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415121.299085, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720056649.932043, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720323285.584787, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415154.592994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720437978.9498, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720473849.744602, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719984649.0919, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984690.14033, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720049900.611104, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720049902.719326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070202.827545, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070219.8164, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070221.892056, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137406.074377, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137495.69452, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137497.797134, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328661.139393, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328739.939669, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498901.295947, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570987.624349, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720602646.235039, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720602812.376711, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720602814.446349, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974528.289353, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395723.591687, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720617442.004095, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719975592.337919, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720057591.780745, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720488152.255523, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720148926.955422, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232410.538746, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720408447.752538, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720242892.942203, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720322823.10199, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720400088.852099, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652752.741385, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720412428.936544, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574790.414977, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720069130.346249, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720157382.402748, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720157476.064866, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720157570.728611, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720157662.381552, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720168580.805279, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720168760.793692, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230288.646191, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230430.103977, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243393.667459, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311604.919662, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311771.258364, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311773.310317, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720324823.664232, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720324825.721978, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393374.344255, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410680.226051, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410682.252163, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498394.961086, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498440.73496, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569716.948564, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569812.275586, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569814.333894, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569814.53133, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719978988.407662, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719978990.511958, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984066.593696, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984323.803693, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984325.863773, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152078.595081, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720225565.930941, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720280378.036955, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326955.218979, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326957.292481, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331017.031137, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720331019.121504, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410756.685202, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410758.796614, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417802.859919, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417804.989442, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487313.059882, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487498.533155, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487500.652063, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487503.708405, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487505.805861, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501546.266299, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501655.51812, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575741.153236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575891.79104, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589520.786652, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589642.390304, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589644.452771, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720615233.591986, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720615337.890481, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719971542.018584, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719971788.12398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720117268.913487, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720117270.991206, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143198.612101, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143429.084839, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238625.308642, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238757.81922, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238759.894117, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330550.917977, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330626.459228, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720378937.313156, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720379038.375789, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720386358.224787, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720386360.275601, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416486.117358, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416608.109114, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493716.833205, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493844.641363, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493846.67691, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568118.486107, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568219.230995, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568221.334344, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574746.351324, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574815.297689, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720233195.120615, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393731.964556, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570257.699261, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720149655.238203, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720352361.227124, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578697.147852, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720411277.985506, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720572981.673421, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720569584.93865, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720311303.894177, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720576463.87807, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982989.782732, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720080708.007665, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234553.333259, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719983711.203136, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720395076.590109, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968905.802345, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720054751.228152, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393228.571573, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720151965.57438, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720265917.280767, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414597.498797, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569352.211054, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720139623.448558, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720413909.371495, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720332156.972433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486770.808084, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570506.129092, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720046377.309817, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720144405.103977, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720311749.460887, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720480404.801297, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719965504.779832, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720489219.425884, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720480774.306063, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719968486.759348, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720229505.650825, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720122526.844622, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720142320.524851, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720320995.267452, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984296.990609, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984350.22369, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984352.257572, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052997.807277, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053049.304507, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053051.378602, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150389.546489, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150391.660121, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720168392.833864, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720168394.931787, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720218901.13549, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720218984.364651, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720218986.444335, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236871.413173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236873.52, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318899.245869, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319077.080816, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319079.181328, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720421585.966107, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720421692.177002, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720421694.269891, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484559.101295, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484634.686657, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484636.791229, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484640.876498, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484642.914839, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568978.955929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569083.551067, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603472.634189, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603622.57534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603624.69381, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720204831.715905, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719985836.773241, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720227063.151216, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720226998.434162, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720413326.470543, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720484747.542658, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719975290.47648, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719975421.539502, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719975423.609947, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719975424.130571, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719975426.224942, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720024823.782769, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720024943.32157, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720024945.350078, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720024945.905366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056619.663053, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056822.318399, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056824.36183, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072281.168332, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072283.222603, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134154.949613, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134376.323715, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134378.416906, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720140112.874786, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720140131.322854, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720140133.38169, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238635.597737, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238637.672121, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418306.625113, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418333.5673, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487528.439985, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487546.337876, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487548.449392, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502509.125496, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502624.411704, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585053.028856, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585055.08891, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719982052.592392, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982258.203523, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985183.079021, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985305.780432, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055777.47168, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071284.174477, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152558.44266, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152671.333552, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152673.415669, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720182134.94743, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720182137.028427, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720182138.842693, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720182140.958073, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227575.333539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227736.260264, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227738.300477, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236068.538351, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236070.60483, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317757.071545, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317866.130343, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317868.22788, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330462.980036, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330707.655663, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330709.750072, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720373940.747523, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720374027.697475, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720374029.799405, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406670.90306, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406844.478936, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406846.592556, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406851.281701, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412576.66958, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412652.412012, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412654.533239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486184.910769, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571066.49819, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720626129.788949, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720626261.332132, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720626263.446226, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720626267.27108, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719972691.157799, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972822.458675, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719972824.589752, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719993329.829737, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053155.834123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053293.330528, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720084358.281667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720084522.554824, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720084524.658959, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153146.842639, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153159.620793, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223041.359927, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223107.178767, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223109.301943, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243608.145196, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243715.813915, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310055.295457, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310225.190394, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310227.250668, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720374255.295948, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720374257.390432, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397033.790744, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397192.93351, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489562.012912, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489620.124167, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489622.2461, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577615.944083, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720595908.263871, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720596022.795818, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720596024.909409, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720596025.112291, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720596027.181848, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720410184.878056, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720446097.457008, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720582142.651169, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720496385.651227, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588018.159792, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719975737.968693, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720069758.403541, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720573220.196789, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720435170.4772, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720156838.062846, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588244.606338, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720072706.921977, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588899.722119, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720058343.607628, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720314365.315505, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720502417.751936, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720302708.367359, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720585704.559633, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984540.656777, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720146973.8651, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720341798.159409, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482149.273983, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570969.604085, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720311167.154928, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720404884.472902, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720481370.176729, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720098969.778426, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720542708.023885, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720149583.597081, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314574.406545, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416038.659142, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572347.697131, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720033450.660601, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720033450.752555, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720033455.770905, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400227.89913, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400250.299243, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400252.394995, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417432.186774, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417504.33498, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417506.39095, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417509.515927, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417511.647347, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417512.311827, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720512787.544525, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720512787.637452, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720512790.509437, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720546384.085434, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720546402.635026, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720546404.721606, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720091612.414745, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394180.692823, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720499565.692616, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720050050.500015, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720050118.092842, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720050225.108458, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720065727.65261, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720065830.735126, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720065888.617825, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720065986.346168, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066099.675624, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066274.481661, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066349.195281, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720151340.048882, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314849.375028, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413869.9313, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720054419.118301, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720399142.008777, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720070403.925696, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720244978.0606, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588083.280232, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720142944.669634, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317829.682224, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720402172.873968, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720135813.27587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720344219.879026, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720587780.127476, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720307062.497702, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720145491.250495, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720586242.178403, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720586566.015615, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720409077.369118, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720569722.833936, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720098442.029928, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720391796.053942, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720243240.863801, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492060.909226, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719967064.859664, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720055971.205432, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056017.075129, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720069354.406111, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720069356.466395, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153990.829373, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154034.130574, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232518.365492, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232668.084829, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720232670.147567, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720247796.598987, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310742.132713, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310784.012123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320091.334971, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720357505.367765, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720357507.406388, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404625.988586, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404726.50447, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404728.609789, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417440.696768, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720460381.831877, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720460489.831088, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492881.459734, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492883.570789, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580680.591028, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719975556.382414, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720231475.932226, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720569569.754826, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720043952.413223, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720225500.222696, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719967819.052883, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234292.697748, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397113.348799, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720087477.672876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720438489.760021, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720577383.739689, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720047896.111507, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720200244.93862, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720464543.942733, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719970307.394382, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719982131.954439, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238111.874625, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719966189.201726, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720150700.452652, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720142072.057736, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720063956.632264, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720057020.243682, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719973656.343743, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719973767.615562, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719973769.702368, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720050422.073716, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060932.515015, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061076.268193, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061078.375626, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061082.695369, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061084.803345, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061088.695247, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061090.795592, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720135057.814031, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720135295.655111, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720135297.734383, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156608.706907, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156610.771323, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720208160.885537, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720208274.821579, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720208276.929569, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223270.224257, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223272.316827, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223275.15326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720261350.082829, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720261423.329391, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720261425.427693, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319448.712298, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319512.283877, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319514.384024, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397163.860459, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397201.824506, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397203.898302, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487465.098454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487616.241062, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576783.799559, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576837.625767, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576839.747181, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720621584.709553, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720621686.14789, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720210871.32264, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720324564.785043, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719976074.774068, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720432422.057214, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498059.505822, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720537307.322626, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720051279.943281, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720326635.291429, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720317156.788498, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720409687.362687, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499324.086042, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720058380.956986, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720150021.258812, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720053489.906165, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139673.741326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720257769.454421, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393246.483443, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653126.121555, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719980029.84453, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720579706.660021, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720044200.360238, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720081853.12837, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720052881.805602, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720072654.6007, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238922.414211, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410048.118631, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720307869.769519, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720016591.216479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720157097.134758, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720238731.063819, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575486.387284, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965711.424761, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719965713.531779, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720049361.440421, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720049363.495467, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070584.34326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070586.439897, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070588.168108, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154076.359366, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154271.555582, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221139.621509, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221264.378154, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221266.479342, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239415.452192, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239475.014596, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239477.07742, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313035.217622, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313041.373706, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313043.420222, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406631.8599, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406659.023715, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484615.165994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484638.913162, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497880.450011, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497934.842426, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497936.912581, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720540604.563371, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720540779.42356, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720540781.553641, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570083.468668, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570174.103962, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570176.16906, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720583667.401678, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719984388.470208, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057777.644161, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057953.012529, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057955.119335, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148795.685708, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148805.802813, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148807.834184, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234649.035149, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234705.911474, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321956.32096, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321958.41442, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720409662.220157, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720409664.333692, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720447795.315077, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720447797.391813, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720483016.135213, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720483018.21033, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720483019.948558, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573042.040836, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573166.473551, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624631.359534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624673.478312, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720072684.014623, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308176.896274, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404626.250723, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719970599.437881, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066959.831691, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067155.392921, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067157.488109, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155932.952678, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156052.447154, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156054.565087, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720176991.157569, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720177007.156433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720197632.204363, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720197634.246364, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720245139.96838, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720245142.060531, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313085.938317, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313087.991269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720382887.239454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720383102.784337, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720383104.858248, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401645.882852, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401875.751914, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401877.871081, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401879.349072, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401881.439362, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414595.608826, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414633.289105, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414635.359202, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417003.580682, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417074.130853, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417076.197409, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480715.553431, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480828.705337, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480830.783164, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720579482.271054, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720579503.249382, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720579505.309044, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720320578.9281, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320637.501704, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320671.3461, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320700.900689, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326925.640353, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326927.740401, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397880.433215, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397991.949085, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407395.883774, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720478571.564518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720478573.689929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496055.710657, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496250.423433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496252.533919, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567595.861171, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567634.8402, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567636.90682, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652785.237133, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652836.758383, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652838.851539, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720076323.446198, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720076387.202961, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720076463.503404, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235511.111341, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235587.152102, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235604.104726, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235788.441489, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235897.829327, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235943.361057, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236088.122922, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719969865.146509, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720088372.900286, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720220494.799398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488909.409034, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720063420.61895, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320803.577679, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401999.385093, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720051291.94966, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720313692.587964, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720509709.170957, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652928.475583, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719976500.586248, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720063184.061031, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720147998.634564, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720575037.093899, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720594897.858543, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720238660.290085, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720306835.46462, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720401110.356341, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719970976.422012, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720051629.137902, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720301759.327348, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720646663.705407, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720077214.628033, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720579842.451312, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720403179.578891, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720573175.772465, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720418161.36421, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418260.71249, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418315.726571, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418380.031953, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491482.634884, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491528.332034, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491530.434212, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573999.084897, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574047.543743, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574049.630747, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720616534.181229, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720616536.227681, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719971505.975792, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309386.016213, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570539.167487, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720026981.201845, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063393.228975, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569870.489752, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720151334.562097, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311454.894847, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720483363.072169, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720051176.858561, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567049.0934, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720300278.98565, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397622.151994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487075.583534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572927.092976, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720588311.663694, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720323338.447054, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720499740.21156, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720239215.924016, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720407168.197067, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720496803.3956, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720578053.220463, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720400566.962842, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652817.676145, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720234566.739671, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720335553.524142, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576366.993741, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720058095.694475, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720499846.305083, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720069736.856188, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720327054.018462, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720446989.50202, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720579246.321269, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720065515.046196, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237193.252454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720402549.014306, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719965737.195869, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057334.427369, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221205.840325, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720366343.985963, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720195598.557753, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719980678.939359, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720144995.169791, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720583721.214132, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720054537.756175, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720182546.976397, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415420.418491, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491014.558376, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568712.840731, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720061881.320656, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720352102.705661, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405007.368123, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720578542.112522, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720652582.644175, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720243826.422296, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719980177.888359, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720151191.015847, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578744.147878, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720401711.559261, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720166076.219132, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603429.438791, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653029.910009, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060428.267185, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720330543.204866, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720023596.681592, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492712.578171, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719969468.250895, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719969673.12603, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984075.563213, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984158.542506, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984160.639094, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719984161.840978, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063496.706949, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063498.73801, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071811.706281, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071892.339384, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071894.401443, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141092.670014, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141281.129314, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141283.221705, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242813.561025, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242887.120065, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720242889.197122, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314744.527265, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314759.642908, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314761.711826, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720371097.307425, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720371255.548011, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720387058.372995, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720387060.502073, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404975.528018, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405017.654969, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405019.759385, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415081.995346, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415260.662438, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415262.742795, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485117.023333, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485119.095263, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499098.798714, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499235.930954, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499238.042676, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569739.038396, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569853.204944, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569855.2363, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720602936.713875, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720242969.422529, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719964838.834772, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720091821.44426, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233192.310563, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328141.79034, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496224.014897, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720152285.903631, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243334.372125, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720379463.678962, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720542353.379097, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720649368.688756, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720226523.433881, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226623.918185, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226651.194519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226742.683406, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330187.550014, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330210.231169, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410272.539479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410274.655647, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480303.2625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480415.671856, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480417.738288, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504693.498524, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504764.21831, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720504766.268173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568377.567722, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568452.706691, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568454.778127, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720150751.139246, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720064945.077586, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720176851.77124, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413751.53369, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720067667.982332, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498323.491767, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720640332.912224, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720586416.962046, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720403065.106609, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720468529.097883, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719976409.626599, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720617974.74258, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720155789.338418, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719965523.519862, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720492317.02938, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719971602.527103, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720069918.036547, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149900.77775, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720143447.493022, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720292005.708479, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720316731.010367, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720061643.180585, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719998587.453659, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141642.077196, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308402.56405, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416584.28358, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720587211.681421, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720155992.271335, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720572458.818891, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720052898.053761, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720221610.587492, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312064.403238, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720147178.948005, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315892.264762, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484335.142158, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720625426.867126, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720225964.225383, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720486617.901554, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720064206.744859, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720148855.512919, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719978022.859036, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720225065.814898, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720379679.901663, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486481.106043, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720072107.565425, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720244247.598994, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720418305.8177, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719982059.871483, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719978817.113542, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720138229.977179, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720069967.627991, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720327850.533176, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720047008.96098, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720399885.70332, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720241326.183043, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719974240.573502, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719974319.570753, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719974321.645618, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720023281.111928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720023484.341612, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720023486.442918, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056803.840688, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056805.906524, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056810.106719, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056812.20004, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070833.346034, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070835.405627, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070839.751918, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070841.8631, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143274.991396, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143497.358536, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720205396.067954, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720205567.621928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235968.291387, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236089.012578, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236091.096483, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720299309.484376, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720299348.029909, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720299350.111093, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320587.866423, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320589.944508, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400218.389368, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400220.487059, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492976.763916, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493019.503907, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493021.579652, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720122662.758187, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720005466.226878, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720152200.991189, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720481835.844194, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580183.828864, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720070662.89957, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720142183.650314, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720411252.551579, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720072507.675137, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720238913.204492, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720218011.114445, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720302385.101079, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720570186.762002, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720157661.668233, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720002096.475822, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720002098.548489, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066947.715378, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066949.844651, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720105199.7729, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720105370.978068, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720105373.072451, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134686.761223, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134688.87969, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154938.58341, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720219977.007902, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720219979.064108, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720250673.20197, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720250796.014257, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313894.440119, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313896.495204, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313896.774105, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396853.1643, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396855.257174, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489852.456446, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489986.86769, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569682.852233, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569767.225411, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569769.334261, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581192.763754, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581262.544992, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581264.629216, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581266.203535, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720226441.129883, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226519.948161, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226639.444269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226731.198095, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226779.385516, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226788.674966, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226923.560385, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720487951.436457, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720038002.665527, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488750.698306, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589885.270178, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720580260.501907, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720237662.32438, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309542.106408, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720573441.412558, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720598006.382998, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720249262.676111, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968867.096755, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406515.635103, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568473.896114, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720063183.618875, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720313109.473272, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720418083.174351, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720106024.609, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720058454.321955, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720062639.625591, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720221670.858026, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496857.495022, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974856.395033, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053608.017225, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053669.477447, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053671.560518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062649.578553, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062651.66265, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062653.377042, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062655.44862, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720082692.43711, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720082771.847834, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153671.808662, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153713.489374, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153715.599402, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153716.387598, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153718.446591, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239246.152588, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239248.241024, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239250.77294, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309956.683905, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310071.602061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325462.049867, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325503.88631, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325506.004479, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412942.492135, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720458829.36376, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720458949.800013, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720458951.887504, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492407.820081, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492444.404348, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492446.466946, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575932.543872, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576033.410802, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576035.469127, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576036.44253, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720647287.059052, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720647289.160943, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720330899.088291, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720081793.462679, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720081976.131384, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720081976.187009, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720081980.325716, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720091170.691618, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720091356.840132, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720091358.928927, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720238399.047753, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567368.683366, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720583646.429286, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720330049.16818, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720578076.222297, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719972331.112716, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720051745.533132, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720146463.601388, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720474541.840768, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720051898.891617, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720173013.609275, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320493.657042, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720345690.851927, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720408818.140609, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720486964.900766, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720043728.363322, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311975.271982, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571578.431424, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719972681.535491, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720481018.937328, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720026382.553301, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720149100.706808, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720307942.507634, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570495.6023, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720488173.923373, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568447.027354, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720567270.126647, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720499324.726509, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719967975.358552, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720326137.056104, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720328587.433829, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720055336.001624, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138863.165013, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395924.519387, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720069032.516709, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720055010.518163, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720099339.150894, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720585549.317132, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720409221.504822, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720519728.003909, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567616.396835, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720244626.143033, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720408635.777109, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575490.310245, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720650559.825556, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720582328.399682, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720394085.218172, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720066065.444143, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720191993.66672, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491329.586545, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720071639.073353, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147406.207381, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311129.234658, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573354.037576, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720240131.733437, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984704.452873, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154844.587696, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720322613.231449, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569714.825725, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720486946.256934, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720647691.877446, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719993805.960143, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143738.25635, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309437.19401, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720398437.265534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720509793.976335, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720629661.586274, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720062670.596985, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720438472.029491, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720329032.038648, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719984110.370743, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719986035.664892, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720241225.374801, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720105075.810739, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720150414.362845, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308174.216706, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412581.759663, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567554.209717, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720537016.009206, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720589963.468469, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720487391.820061, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719975756.8334, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155078.652264, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400698.199527, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496832.791723, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720018681.490249, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136925.765051, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720299976.82238, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569027.317754, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720154725.361924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243905.535885, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315512.512864, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720588095.521256, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719983442.727069, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720152453.391462, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720405182.158931, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720575807.583852, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720069878.030512, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720168504.534482, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720239119.238416, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720576430.211377, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719972965.48613, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720240976.867243, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404977.394327, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720537004.359466, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720487019.528315, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720581959.239135, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720652926.990055, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720052099.960777, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138855.98453, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138921.586511, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139014.744606, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139182.595009, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720139192.3206, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581909.908771, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720065955.899244, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236828.579322, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308640.597753, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720579634.738256, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719980159.276761, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308552.424302, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653256.063729, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719985271.443965, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720220543.115385, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315297.143816, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720330015.747888, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720481610.656596, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720224041.283015, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567371.834809, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720244217.827624, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720402557.505715, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502124.284452, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720415547.576014, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720531682.711315, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720407411.272993, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574508.629738, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720257290.163002, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720492975.717018, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720144145.711511, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720401163.125022, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720355601.346282, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720572069.286814, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968339.260056, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968341.365428, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968343.993978, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968346.031381, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968349.431552, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719968351.559689, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719976134.941126, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719976278.477066, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719976280.56988, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052757.855887, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052759.915085, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720110094.313929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142517.707832, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142570.10559, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142572.151412, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142576.179553, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237055.807105, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237203.321556, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237205.419793, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720316912.566247, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317055.804333, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317057.925258, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317058.399149, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317060.481448, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393849.766518, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393921.300236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406796.853939, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406798.933918, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482599.505433, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482663.255581, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482665.27704, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492023.699542, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492025.737059, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500142.609638, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500250.895423, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720525828.241699, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720525830.335737, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720543473.185403, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720543629.193018, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720543631.258205, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566115.315069, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566235.252146, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566237.371673, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566239.622085, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566241.74061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652422.12376, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652589.161105, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720332940.235911, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720065527.859172, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720568368.543876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720635472.219669, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968828.538353, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720051948.377763, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720299205.556357, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720235830.179481, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235953.147018, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236018.20472, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236089.138704, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236119.593712, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720236141.83499, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311050.201652, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311052.280309, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395484.534496, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491406.080018, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491430.598198, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491432.661821, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572678.481313, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572808.45491, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572810.563889, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603175.70942, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603202.06502, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603204.156746, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652491.405509, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652598.039059, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652600.082367, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720153161.725292, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720494662.408865, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568597.855422, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720416466.753208, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719978991.390168, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720072031.976782, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720584690.251602, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720575076.950008, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720231712.798613, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720398045.987903, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720056840.047309, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720625851.477544, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720053429.359158, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053508.29626, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053570.605172, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720053639.380777, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066181.00997, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066215.053405, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720066217.116517, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143779.66573, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143781.713526, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222105.35254, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317654.056711, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317708.563828, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480329.549535, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480520.417693, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480522.54519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480523.499363, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577037.242221, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577039.306434, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720639329.717862, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720639469.331454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720639471.36127, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720024453.629276, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720316176.77774, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720068883.919311, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319773.101818, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586957.747953, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720056927.404781, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720054270.638059, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153565.870327, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720334693.538652, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720152641.309698, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720576318.23299, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720404934.034946, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720476937.980269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652925.317718, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720583121.659416, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719974918.036807, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720052839.789235, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720309756.887443, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720214816.601474, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720628643.350003, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719990813.089809, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312746.860016, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720072040.294779, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720573666.820699, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720221192.01312, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720143165.437476, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719965593.95106, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062861.422969, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503564.270709, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720310060.645551, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720482309.217878, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720591036.349001, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720157768.51272, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720149445.473387, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720438026.869011, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720060489.013219, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720415886.629529, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720580867.871164, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720414273.276015, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720487097.033528, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719966569.062726, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719966533.368239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318867.369239, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720424434.84027, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566607.607309, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720608001.068576, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720062804.379267, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226534.49236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321084.499585, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720450358.303395, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577114.020932, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720138095.209939, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720109654.682718, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720109832.815741, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720109959.88633, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720110033.900336, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720110090.159457, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719973270.54798, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720404747.93651, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719975896.00888, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720412877.994145, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720488415.324703, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719979329.168652, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719979433.834943, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719979537.706541, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720054525.517489, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720054576.808031, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720054637.310552, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720008269.86362, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720228186.690288, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719980906.390651, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720049804.519108, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719982824.989151, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720052793.231176, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416383.522419, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576203.462386, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720141956.096351, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720501761.653384, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719968214.670337, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720061582.741936, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148352.805998, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720320650.836088, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720480540.757287, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720066746.296404, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720470635.779369, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720036143.99876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720235115.25383, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720325739.301864, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720366758.48691, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720579671.285769, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720406674.612278, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720569843.609239, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720060843.491976, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147665.305258, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720501529.904655, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720046373.265399, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720046375.332994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068144.411279, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720068261.195225, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720131629.331825, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720131717.731289, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143208.108341, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720224375.336718, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720224489.89131, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239983.991454, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720240023.957522, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720240026.023994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720288870.449116, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319014.330473, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319153.071162, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319155.11854, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720356008.754634, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720356170.017209, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720414281.753569, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720466888.126284, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720466890.175399, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496852.884055, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496900.157534, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496902.257177, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720517711.484252, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720517785.617389, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720517787.722386, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574636.301281, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574638.402501, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720631962.467861, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720632073.350096, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720222983.951049, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720416117.193584, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719971140.695348, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720135102.372106, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720241528.560118, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720494221.442123, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720321074.976216, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720409891.326419, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720048681.074873, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720048799.279747, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720048801.388645, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720078114.283264, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720078331.228227, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143813.123392, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720143818.771163, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235193.521271, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235195.596896, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325140.395885, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325267.478348, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411316.426439, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411410.991238, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720411413.049352, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585972.027756, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586043.355429, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586045.457795, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720615162.541609, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719966754.275194, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720490216.464205, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720553382.681907, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720002644.294528, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720230090.842106, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720146769.696788, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720165756.310512, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410912.566749, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570647.832366, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719976353.576494, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377185.297147, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377289.215042, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377308.468995, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377428.407697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377485.735576, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377529.508166, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377719.383399, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377809.666048, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720377903.918773, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719980213.693083, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720140384.252931, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720063871.378525, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720573199.935932, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719985832.719319, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720406386.34727, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720235695.246766, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720397629.747797, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719968874.938189, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719969009.652547, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985700.913806, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719985791.512554, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148300.05719, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148304.627225, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148306.685703, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227741.213642, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227808.775173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295172.811284, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295262.745855, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295264.827116, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295269.130924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295271.214758, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295276.000757, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295278.050173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720295281.951474, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314791.722567, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314793.809493, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314794.091414, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314796.180282, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720334621.693568, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720334651.208509, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720334653.289286, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405990.429231, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406072.368399, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406074.479232, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502938.778116, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720502940.865312, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575136.293441, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575193.500487, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720575195.593287, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584066.099625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584068.181406, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720401234.664166, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720338995.593562, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720569421.058122, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720152780.103003, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318021.21162, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568682.771219, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720153767.474128, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153989.99445, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154117.339532, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720154188.47243, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227169.047901, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227171.113334, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720290328.719511, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720290370.18464, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308949.583306, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309021.205367, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720309023.255742, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400031.238045, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400050.534361, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400052.591865, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720475517.057002, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720475631.221119, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489341.891834, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489520.813888, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720522911.41822, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720522980.415637, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720522982.44762, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590435.585175, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590601.259611, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590603.315457, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590604.638539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590606.730642, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720612053.860624, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720612129.921877, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720612132.011818, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720426949.173587, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720569102.034496, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720034790.744638, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720307075.973997, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720226287.705985, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397684.607266, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720488997.884315, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720228730.18975, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407495.769529, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486995.921451, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720489080.310875, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720579311.992295, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720138007.433538, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720243741.609597, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720528666.459324, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719970772.701878, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720141632.061506, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720068110.038208, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720047191.032235, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719976436.118248, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720307037.853977, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719972036.639217, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720057689.829017, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720110461.39165, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720507249.36072, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719973197.847086, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720069338.721539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720524537.017222, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720603176.268707, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720142471.621654, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720221877.173433, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720141771.947396, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720563222.366935, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720237444.558492, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720586951.821255, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720066787.226665, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138501.376918, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720332897.490345, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720498267.095353, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719979972.999784, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720326547.318274, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720156142.458551, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720222674.830191, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719976247.399205, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719976421.138728, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719976457.121053, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719976566.522486, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720060116.807539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142201.528128, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142320.790244, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142322.873716, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142323.209429, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720142325.32365, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720158309.47212, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720158464.699924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720158466.803077, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235827.780639, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235829.873017, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235831.516786, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720235833.64015, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308111.792929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308113.917634, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330424.153222, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330426.274619, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397440.529792, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397517.527169, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397519.567891, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489794.692916, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489888.559008, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489890.678539, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577363.385966, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720577493.034855, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720042932.668232, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720059740.224971, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720141837.883794, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405792.751871, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720050443.838424, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720124719.146549, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719974887.67444, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720568466.68215, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720065592.314345, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720205463.888972, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720226332.701569, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396620.155135, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492327.218299, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720574416.447233, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720045016.618738, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720041923.403398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720041925.529856, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720041929.344695, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071082.001532, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071201.167727, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071203.259989, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720113938.478909, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720114019.141219, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147954.114345, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148058.186186, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148060.244565, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230463.28606, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230465.339869, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720306384.513301, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720306386.603107, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720327575.975525, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720327821.751969, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720327823.781901, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410348.159738, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410448.341114, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720457570.237639, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720457731.119754, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720457733.248545, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499264.385485, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499470.033411, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499472.085357, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720543986.94937, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570525.581032, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570749.619565, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585164.854344, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585249.748529, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585251.810485, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720489237.597076, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489298.656835, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489340.853931, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489414.715662, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489578.362748, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489722.080922, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489846.161597, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489902.616032, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489979.179271, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720226541.700259, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720459357.712795, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720137147.179349, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720241160.346244, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720393844.000636, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720233961.944441, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720475993.227865, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720339946.523179, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720314335.142585, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720307070.122528, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720396806.823553, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720134885.254524, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720582472.172677, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720064989.52196, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317471.54011, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720405569.646675, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720230240.375249, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719981989.67667, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982209.356573, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982211.412871, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719990729.511533, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719990731.571772, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052018.486278, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052084.895512, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720052086.959136, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063752.458627, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063775.402517, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720131365.952047, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720131512.217778, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720131514.344434, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720155954.588913, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720156049.221823, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326057.45718, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404760.882693, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404806.729924, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720404808.834418, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720416517.018963, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720494367.532053, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500247.551019, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500294.606063, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500296.694825, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500299.259697, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500301.365635, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572338.244531, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572428.794186, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572430.860491, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720600877.354363, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720601092.109844, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720601094.164843, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720230142.987461, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720040834.068992, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719984036.646786, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720138775.775437, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720337436.06649, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567415.54222, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720501680.278938, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720645969.459141, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719981148.135955, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720574648.013669, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982323.222591, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720101646.380659, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720493833.121559, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719977634.84991, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720494761.805988, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720595943.849674, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720155432.624618, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720500643.020756, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584683.624928, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720245035.196003, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720313673.855042, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720381149.495776, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720019520.657419, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719981920.434976, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720128572.036838, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720136202.220094, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720279940.922158, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720462395.987553, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720653383.244, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653383.325, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653391.627, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653392.102, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653392.298, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653394.934, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653396.411, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653433.093, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653433.236, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653434.991, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653435.037, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653501.654, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653501.71, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653504.799, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653506.446, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720653507.872, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720654003.023, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720654003.148, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719977539.575178, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223726.13705, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720396336.894644, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720587683.68083, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720327049.710872, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720223003.678086, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320656.874702, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720149475.628567, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720228859.277837, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720049864.230497, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720198432.201466, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719975613.439717, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719975648.049123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056914.90013, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720057026.542911, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720061926.526142, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720062007.614611, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147419.43368, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720147421.485277, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234139.651394, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720234141.758276, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315191.984726, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315194.093018, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315195.836394, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395738.54726, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720395740.684533, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410342.218884, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410455.568303, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496479.412713, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720496636.329168, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568810.362519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720569040.475975, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652557.884167, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720652630.129755, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720233899.203213, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720463796.00711, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567454.878169, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720218589.331391, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720572246.733219, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585861.133309, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720030179.060188, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720330759.17762, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720494515.69797, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719979902.797865, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720070638.173492, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070819.083453, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070899.802295, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318683.767078, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318886.533145, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318966.57212, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318995.968059, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319139.50433, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720146380.443011, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720567703.854081, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720485224.936769, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720039180.636756, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320703.675688, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720572877.111346, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720149009.624794, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720146066.037668, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720233446.585623, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720397647.223612, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720071535.98588, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720222696.675857, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720581710.534385, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720320564.297259, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720221596.179609, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720502714.197196, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720553799.408143, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720244362.654861, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720412405.21556, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720566429.648086, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720225993.003411, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720576860.143664, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720050680.82043, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719979231.190542, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720395944.084001, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720483644.896944, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720238837.512808, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400917.965225, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499924.896186, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978670.650293, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720312908.844749, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720064475.615309, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311005.200102, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720398033.682041, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1719974842.261587, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720070482.809945, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720492054.306253, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719985346.86067, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720494586.311794, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720151598.2787, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720243336.399964, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394460.006175, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584803.786632, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720044414.812182, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720161374.32603, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720242818.837344, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720407806.948096, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720511793.967125, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720177465.166679, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720152899.613121, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720144169.768087, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720050900.326256, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720592651.789908, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720136535.399876, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720345016.561725, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720148677.039505, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720103982.765975, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720223275.492349, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719966246.265247, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720048787.249996, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720588475.186395, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720406823.932911, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406854.864424, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406898.943281, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720106989.608336, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719965156.233365, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720156113.65034, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720237894.767081, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720236335.89358, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720311377.453215, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720406308.416613, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720580297.715893, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719983515.156201, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720243011.26844, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720412740.206646, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720573676.882026, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720069113.016836, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720065156.88711, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720342013.62189, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720414414.37316, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720576057.542994, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719965980.977528, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720328208.291947, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586256.843288, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719993285.557781, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720157474.360894, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720317049.692797, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720418157.354486, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720492206.117992, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720566094.344648, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719974058.930323, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720059173.893018, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720517061.661773, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720052300.009912, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720447926.535749, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720060153.321408, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720498576.79341, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720415193.154478, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720494529.74019, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719980354.732889, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980356.852338, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980359.805901, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980361.898886, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980364.204398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063622.210305, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063766.011158, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720063768.060823, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720134932.57792, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148426.91756, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720148428.987966, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237634.85931, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720237687.961173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720321596.679301, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394727.592533, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394743.278857, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720408408.443408, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720419213.527306, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720419321.981, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720419324.073269, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497577.385151, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497694.789568, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720497696.883431, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584999.597212, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585001.687849, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720585005.063862, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720134251.830614, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720407054.526951, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720543564.686466, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720395362.215692, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720500480.122778, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720058412.695383, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720228775.865928, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720503282.31697, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720614350.980502, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982519.149294, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982589.903207, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982591.966235, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982594.824529, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056059.106374, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056099.353137, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720056101.438857, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720084141.137944, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720084195.578773, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720136869.202173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223064.342828, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223120.591787, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223122.696149, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239556.237398, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239630.045363, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239632.137037, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720312988.468776, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313161.594176, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313163.656358, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413652.862676, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720413773.395596, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484458.010065, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484503.114542, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484505.173957, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720570920.862746, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571065.994777, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720571068.086575, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720138634.579801, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720394701.653755, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720404840.88735, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720570759.329975, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720474997.255842, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719964981.812038, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719965079.656724, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719965081.766625, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720017945.346535, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720018196.228851, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720018198.332037, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071944.789981, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071989.860765, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720071991.963241, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226601.357382, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226662.671017, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226664.720854, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720226666.697991, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720245432.525672, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720245586.690365, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720245588.811888, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313288.75101, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313438.935319, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313440.997298, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325185.461926, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325279.708469, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325281.823994, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325284.895173, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720325286.963747, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720351212.007507, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720351417.722923, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720351419.786979, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410234.644402, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720410236.746729, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484087.598816, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720484089.656452, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720560975.588946, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720561062.767708, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576170.001406, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576274.339938, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720634969.318238, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720634971.383262, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720634973.669218, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720634975.727614, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720047138.987663, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720239116.860589, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720567216.089602, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720062114.160483, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719974901.32474, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720224712.94567, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719985511.407849, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720140363.584567, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720573348.34834, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720649971.95392, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720325668.53657, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720407800.484026, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720313988.784401, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720137608.121513, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230219.916298, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720576804.122481, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060264.40999, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982324.891431, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719982326.95929, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072365.964045, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720072368.013382, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720185779.887725, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720185782.013458, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720230424.054008, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720329463.631365, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720329503.210461, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719978020.337077, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720378278.012205, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720198700.302556, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720417057.718199, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720584860.786802, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720627126.675399, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720072022.286212, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720366423.980574, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720221042.039954, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720060635.731519, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720210299.946067, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720283154.070272, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720402469.930097, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719972611.185894, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720227219.185837, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720565623.051185, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720060770.015072, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719979906.872722, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980094.376717, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1719980096.476308, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067152.682142, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067174.598435, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137635.975558, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720137733.593423, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720224539.774939, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720323664.982932, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400336.830381, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400497.747426, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720400499.843107, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486404.88152, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486460.387837, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720486462.465262, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720494960.521565, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720492283.522426, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720588131.39025, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719965172.184078, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720313653.224728, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720133961.331413, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719969914.979558, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720051155.959984, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720318569.685111, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720499729.951734, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720328273.411971, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719982315.965122, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720423276.150804, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720586911.740203, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1719968679.211527, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720063388.278848, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720416336.796001, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720398479.735494, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720493260.033312, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720489609.661573, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489700.750791, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720489717.546997, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720500732.208908, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720153118.225066, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720314031.634943, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720590337.724401, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720070140.554847, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720137932.433554, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719992154.926275, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720320574.945082, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1719984916.520671, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720569849.178614, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720140614.641046, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720395184.350061, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720310387.035179, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720473940.199193, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720062920.051834, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720226181.474055, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720470329.222623, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720582334.499662, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720443828.896214, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720580682.756419, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720226425.344326, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310598.961662, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720589761.631011, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720584698.862455, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720164879.185564, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720323846.480885, "uuid", [], [1, 2, 3, 4, 5, 6])], - [(1720051096.071376, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720157299.452758, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720223524.412388, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720326592.782923, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720578100.065601, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720313647.455076, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720559337.211802, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1719981335.449573, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720067595.1521, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720319132.823969, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720491547.165147, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720019886.753884, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720153101.556554, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720313536.357232, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720485395.202604, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720568839.562655, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720310841.194378, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310912.574061, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720310914.655803, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720587828.804404, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588071.078858, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720588073.115074, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720055953.618503, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720223652.080905, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720308372.703732, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720624033.359415, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720173756.125859, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720315128.683231, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720466410.646777, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [(1720157263.810637, "uuid", [], [1, 2, 3, 4, 5, 6]), (1720235081.49838, "uuid", [], [1, 2, 3, 4, 5, 6])], - [ - (1720229216.005254, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720557735.625871, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720627294.521232, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - [ - (1720394336.326148, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394382.775033, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394404.054186, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394488.655765, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394583.815862, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394609.744123, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394643.351845, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394661.447752, "uuid", [], [1, 2, 3, 4, 5, 6]), - (1720394715.354794, "uuid", [], [1, 2, 3, 4, 5, 6]), - ], - ] - for b in a: - calculate_funnel_from_user_events(6, 1123200, "first_touch", "ordered", [[]], b) - - -def test3(): - data: list[Any] = [ - (1609545600, "11111111-1111-1111-1111-111111111111", [], [1]), - (1609632000, "21111111-1111-1111-1111-111111111111", [], [2]), - ] - - f = io.StringIO() - with redirect_stdout(f): - calculate_funnel_from_user_events(3, 1209600, "first_touch", "ordered", [[]], data) - result = f.getvalue() - - assert ( - result - == '{"result": [[1, [], [86400], [["11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111"], ["21111111-1111-1111-1111-111111111111", "21111111-1111-1111-1111-111111111111"], []]]]}\n' - ) - - -def test_strict_funnels_with_non_step_first_event(): - data: list[Any] = [ - (1609545500, "0b9f49ba-2c66-475f-b7b3-6e8acdb08a37", [], []), - (1609545600, "11111111-1111-1111-1111-111111111111", [], [1]), - (1609545780, "31111111-1111-1111-1111-111111111111", [], [2]), - (1609545840, "41111111-1111-1111-1111-111111111111", [], [2]), - ] - f = io.StringIO() - with redirect_stdout(f): - calculate_funnel_from_user_events(2, 1209600, "first_touch", "strict", [[]], data) - result = f.getvalue() - assert ( - result - == '{"result": [[1, [], [180], [["11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111"], ["31111111-1111-1111-1111-111111111111", "31111111-1111-1111-1111-111111111111"]]]]}\n' - ) - - -def test_strict_funnels_with_first_events_same_timestamp(): - data: list[Any] = [ - (1609545600, "0b9f49ba-2c66-475f-b7b3-6e8acdb08a37", [], []), - (1609545600, "11111111-1111-1111-1111-111111111111", [], [1]), - (1609545780, "31111111-1111-1111-1111-111111111111", [], [2]), - (1609545840, "41111111-1111-1111-1111-111111111111", [], [2]), - ] - f = io.StringIO() - with redirect_stdout(f): - calculate_funnel_from_user_events(2, 1209600, "first_touch", "strict", [[]], data) - result = f.getvalue() - assert ( - result - == '{"result": [[1, [], [180], [["11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111", "11111111-1111-1111-1111-111111111111"], ["31111111-1111-1111-1111-111111111111", "31111111-1111-1111-1111-111111111111"]]]]}\n' - ) diff --git a/posthog/udf_versioner.py b/posthog/udf_versioner.py index a9c7c5c383127..3be55d183ef42 100644 --- a/posthog/udf_versioner.py +++ b/posthog/udf_versioner.py @@ -1,7 +1,6 @@ import argparse import os import shutil -import glob import datetime import xml.etree.ElementTree as ET from xml import etree @@ -12,7 +11,7 @@ # 3. Copy the `user_defined_function.xml` file in the newly created version folder (e.g. `user_scripts/v4/user_defined_function.xml`) to the `posthog-cloud-infra` repo and deploy it # 4. After that deploy goes out, it is safe to land and deploy the changes to the `posthog` repo # If deploys aren't seamless, look into moving the action that copies the `user_scripts` folder to the clickhouse cluster earlier in the deploy process -UDF_VERSION = 1 # Last modified by: @aspicer, 2024-09-27 +UDF_VERSION = 0 # Last modified by: @aspicer, 2024-10-01 CLICKHOUSE_XML_FILENAME = "user_defined_function.xml" ACTIVE_XML_CONFIG = "../../docker/clickhouse/user_defined_function.xml" @@ -35,8 +34,9 @@ def prepare_version(force=False): raise FileExistsError( f"A directory already exists for this version at posthog/user_scripts/{VERSION_STR}. Did you forget to increment the version? If not, delete the folder and run this again, or run this script with a -f" ) - for file in glob.glob("*.py"): - shutil.copy(file, VERSION_STR) + for file in os.listdir(): + if os.path.isfile(file) and not file.endswith(".xml"): + shutil.copy(file, VERSION_STR) base_xml = ET.parse(ACTIVE_XML_CONFIG) diff --git a/posthog/user_scripts/aggregate_funnel b/posthog/user_scripts/aggregate_funnel new file mode 100755 index 0000000000000000000000000000000000000000..04454c7371931d255eb56fb38e3c04159c329622 GIT binary patch literal 680624 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

e`xXYj1kcj542upFh@b2-GksWe zU;dI#hq;yzy9BJUGdmV{Dju?p$NTw5G*%6DQ59H#Y33 z?R~>lU-Eo?$={9k^{BVb+OcMb1A7B&_B#F!uP*u$z}oojUVfX{cyKFVBrcy-YdrY( zHJ^qdJtMM%GK^i~HfxRy9fU~;o47sp`Y+0FT{t{uZAvk5C*cV!~=U=iH%>er0O zQ3$Vq*5cam&Etv|l47IH2TUYhj~g>?j$>kRh#WK89zZjG>m~n;t;VhAf*Dw@ff?(8 zf)jypk`?0xD_nvVC2$7ebXC?S zTytkO2(w!RL5w!IZI1fNOsdJI6HyJpytQ|razsQpofy2via{*mcx z7mb$t^oRSkSFg%7;7ZcjD>li|>!D@EgtreqEvDb($>`%^_>>+;a01PAc`5;RKp%_; z7kZC|Tc|Pn)*oVafhta@U9;KY=ycSsdBgEpW-M|EtxMEdZbvMyV8(}m_)Si;`eh?>3F=f_{0D+sDq2SFXA*%Kp9&WNK`^)w zsaNfym&>B3$)d+V01xLC6>B%qh{}2FXwHuOoHwG*tZEo*%SNfWG%q7&9HWhEUCML^ zQ@U|0mYR{amVl@%s4B zub~U0>*HVGQO)N(|B#KzN8UBD5wk8<{F4s4q^r6D@#!ZFjl=CJYXx$AB8-)A{D}HR z;~eP{_+PQ&>yQu`DKgexiE&~j{ELdB0q0O=s50>o#+qZ;_`~G0kR`M|eLeE`5POIt ziV5Ff!bWV+bOI3T#aQu?qQ0@A`vS50&W5%`gHgW)u?qwH9CV_R`pT`9 ziQ3HHXk)Av=6NnsRTO+Ebp>v5+G3p0tW>ciAO~QZ`>PDTN zmAf;gU&7`ItZ;)9Q_gE3I#b$>dU|M%))rTPpG+GYIugr><8d!~_V5~{Jp{s6S0*y0 zH?h^oW;45iaq*@r%-FQ)P|ysh3oX0CSYI?9TLBq(^oK`AoHFQ#JTs@mH%6XJ=P?|TVw3-h+sIzz+={6YrgPduDB-9~P_REmn$gzH6`6HJJ07gb-(yL|E?m2q8P{%H zAeJ8Vb=Gyrf?^BV@|NO@@q~&q;aN8j53WXz1>$b98Jl$;Q%m0jlMHu#r{QksHl|FT z1JIaKd?GGprr5(QlMf}kugSF3De@Iq>z>)2iX~{x3Gzp zdP^A0SuY?@y>uj4^Kg79a!$jA$cnu$=d2o(jZTGl5w1 zcz+BFGl;4fHZwEe7vnWp!iUnM&(CRNHh;>F8y&Q;jFBJt@jBk@W-Q5}Af z8}U8p%{4HJRK?_kS6JPwd$HS>d~^ql=rMS@5=J!HJcK8#`)3^k_ZyaV9f~}937SZ* zM?PUg^T=%dt|Ie#+@ukP#nN=vMyRn6Q(sCs706<9Or?@~O-@_$6N!Vdf z)(Oo->sJFzF2H@-m5kG(Tbo2QaBcA+NU=xBc--em2Rss^WI;PBhUwk>L+mpnzQFy| z(Itupp{Lk*jE&IY5B(HH7I%Eq5gW_rlK45!wyoAPq4yEN`O>K7P7F=PphFZ;O`?H# zXdn=uwRI(p;Pm;IVC#TC+4U0?C^%6VwY6g*Tx`D7_fx^_^&ndt6T)6keZRD2eYv&_ zlbEz+w2I1>y$B__(N&vyo`x(Tsr`wdp8X^JAe~)^O8QebvSW68?Ee*JWajjKpbq2C z#Kk$`EMc#|0Ud+A4mmfey=N?td04G@2P9`&^+PxW02%O{2F}}X|2)2GILQDyg9G{1 zDSoT-b2!MrejtA$Idzcc!YseSv?d9YC5WP3a)b^BSR`!}!wozHCsd+%iwLgd96!)E z{!jTcbFluCU#5m)guy&b48gH~E!q1r7j%1)58)NoJbqxU>h@d1=;jEz`ClK4vk&Oj zCXUDsd0lQ}35%Ki=`SCU;aeiD!S}6Zm z@iI}LoFCWyOY>vqIWawc2h7J*nKwW7n=$yoSOJ~sGPh88uxzki9k}UpI)ydyiMY@f zpGO)YUpaI2`6}$GY$rybJxE``{Q(B)?`f^_r!olQZh8J-9lF;k>XtUFOWH8Zqo<5t zDFm}FIcHGVFayuYPyViKlQI&Q=d^#pf!jY(Sj*RvKl^_EalSe!UlGfQ7ykj;0Db?0 z^9(;@4xVvZ|6-p1^uPD~=u5waclm|qM_>FK*khj`-G+xz`=r@JzxA}ACsiqBvl4*b}>Rq+F@o}AB=lWe9`Zbut*MgJ294!7j~c+mk*+6$L{80!2NlAb;k zPdn`=XwpEYG$x{tgV=wAOv@#SHa$w;Bm3a|aj)8>as8B=!!g5*Pc1R4H{$5@M)Tnd z&KEz$mAkRw?KAG^Gb1C#wU5H<6i)QKcoEJxp?rL*ulKF7Fg-yWk)G``d+Ae6@?$iD z?F|Dx!tc?JRwsM0#q`DFV#BjJ-{sYa z-j6K5!hc`r@LH>{cFj|~AFeb0a8l^8bctM_Ap!QW3n?)F7$32*b=AY6Q{hi^9l-Y6 z{zRSif$}DvSKfp$`x{kXjJC@`mgueWCj^B?+gX5xSCLF{m_YK_U{&X*FiGP~o!D2a z?*dKTLg{hXn!=GbI{}-WW)7?zlXqnKeO}|9KC;1R;|4kyzGfe;;m~oFTdDqGGAuN0 zI5Qi&^P7sq{K1Z_L7H&P(v?=9D3S=CBCfvBWwNMG6kU*C1Wmy;1nsViFsM$#Q9)Wb zADiOZWMasR;}At`E@!G@XSnJr;>p6c#4SIQ<=jTDEVj^`Z|4@-LjoP{6-<3rF~L|KeF-oX@%b{$Jr=z-*V9ThL{6x^24= z{XK55HFOrJ+Tier^);6&Tu|MEq%DjMIQnK6fq$?BJgtIELceCCp4sJ0R;%c*DN?zL z{xa@!uF8TP=!u7Zl&&k!#W5HyI%~cTyNM7<( zzAy4)xHPse^j+K^fS`Nn)4*Fj1Rt;x{`ftjOpZTJ{W)LyMngHi_`jz=D6jPA8#p{g z{b7yqBOKQY{b@UARDWdq#@gwH^amLV=?_NBe)FaY+_b{KvwdIC-N2OM_8BJ3S{B_00dnwOfdF;qul?s{k!wB z2h7HsR#vgb)keS!Qf3&-YXh-*8kQwi2%YN>{)M2k660={(fi z;KTvbl?ZF659ym-hT|l7+?_Nh7h^z{kqtbc!Ps)%`YQQLY^JF5d6>e-Rwm@qGB!TI z4Ou5P5&KM>^)(}zqUFb>TXWaXF-L7pUDans^yiS>;+}n(#m^-ce`TXwf_!8=vJHnH z4}zayV5jV}Kz08OPc>K@bJpMWvBT?Yz7%@QAL%XfM>ZDW$l|he`d3-{Mym|gb~_Q+ z3eIG$b=a9asQxrp2p((387#+h;2>xHX{IyuB#<$|Lj^Jh$e7SyfQ$|OneTR8ys6un zy9Cbi-?raXm5Iu&n7xd9%(Wk3^NVUZ7LvBM)LM^Q&(&HVh-J%Yo?7d9>#0a)ytQic zvKsO6w92i1>owz^z}io(7i+D4F$IbQzx6WV=jtF}yqIF`#qX{zk8x-Hi)l9^n>ZB& zo$MCByUgC#J@u8(iV2pjp+N` z)d}zUV6&vZ&f43Xa%0OESpy|FJG?9MHax_)QRZpY6gq^aj`Wv|)LALyL?2M;vB*u5 zOV+&Y;Cbqj7gdLRq;%TobC}O)>c!gLcMrkFUIMNAOE&vUKJ%A6vFC+7h#os88EwBp zGXd-T9@D}K$=aTDey14o?Ve|L_m0CEKO{~cLPqmZ{316%>|2pln)la?jl_d$*SzKMvG`N<*1NTlH$2>|Y$*BIU-I#+AyjR&rSQAXN`kje zTvNR}iohy|2aEwz3F9_iw1!Ek@l1k5MN)6F1gV&iDGVe|WFiboNpEfMd)N?t(}BM} z>@Rt;q2$eg1#1Ck%TeE!@f-ff;6rpnT_Zcj^zJyUj#}XB-8q%Q@9o`jNNw-XM5+pE z!=j_h+J`D*hs+#d+`TOtbBvTcQ&-Y!mV5x^K)e1&P=;C2>=TUL2aNh1X@rBe z%jN6&J$2SV1dFfUp`!yOL*_%Zq2Q7$uM1vnR=!kcy=<=ea8YeT9h5FOt$o}Z^&%OWPS$c!~c~nzoI-q*oay3lDKdz@+TZ988NNmTC5)fcy&{AvT?u; z=i4SFe>-oSBl#=*s!Svw|MfTrc5fynkHDX+H7no4K~>CHE#HBJB5w>QSt-`b9biao zyx$tZLTsHs7Dym0wvnqcoKze3#}^F1uwxH(bGyh7JTl@5y>G_GU}^}K;_0XrC1z|M zN(DBzn~{y~^y}u9sLak5REac~dk7n~JsX5c|Kz9@lMv`bq1&Hl#jw-v^bq%&&~64N zRB_jB#uj+HxXs>43w)@Vc{)-xCRAb`*W$(;lP<<~YWhtxcBj`(@yDXxGG3jZn9hxO z{m7irM+$LjX}(J=s8-{EgA2uR;K8}qbXJ>@q&xkB8N1z^AO$Gj&nwd~ytbJ$HnP0e zj4gAmd5fMQjeJOE10h28^teT*iYw zmw8HXIZ{gcjkdVRGS?NGUsmG^h2S`x%eNa^0(W5%y8^T&ddM*OjxjS+4KS}6$pg*0BdxuC+V zX)FujxUmnyzNH+805YX-UGH+VCDIcrx2H>D^QYCAMX1p}ftp?KQVyfBU+g5ztw7v8 zI0cRr&OfcJas&f`*m7Tb7JtK?G8^KHT_AGFS#Yi=NdEaFo6G!>UCw1wxRo;E2)^%+ z&Gdpq=)0%_J3!d@IYJEO8gUq9r7Kf98PBK{FYT->SG69@TH)h-QGI2O;K8UbyJpW! z-wd}i`-t^sUVp}eNoR5^;Xlxp8*P=TwtfM#lXkKHU)&zN|H%*ZADL z#^rf&?lntg$=fZ9R zZRSPv4!;99fca``egIqQ=Xu6@>~W1h33$>vGxf^g|&xb+kA+VZ&^>O-TvVuZ79g`jQd({(T-Dy}OoE&$A+^KrHDbzb7 zdKzwXI3hcenZ9-@m9sC61M7Y1bMeb==uk9--P+eSi%sspjL-eOZ;$gkUo$h0F?yP_ zJ~J~<2B$Q{ukuk4-#?f1y`6qXsXLm?lpc*nDAzGJ;P6ab);PL<0j>n6_~X~3f0^XZ z8llJ5E|wR4*pTi^UW5{(*+<87Rv}j76{l|_fU6@0> zNf>B8!(L;^NP7(cBj{kzoHKl{ye8MYVmxH+E86GI^Vm>@KXwTwera0jU?7Y(#O|SN zFfT@ws|BgwUqV$W2FGZEu4XoIoHT;4gb`(!81=YQe8p&gW3-aS=!SpI82$0vg5R0a zU*RTQ%UT;^x0HcNoV)I?1CtIKW#|{!e?Ljn8L|MCX8D6xIr1#qscbqv%S0QHc%Ee| z3ab74ECb=t4vvFETU-kT;Rb4(@m)SHvmdA8adhK;@;l(4(RMh%ob8ZU@k(SjGh4;_ z%CzqE4izDTb-OprYa9HK5lh6AevjgC{!TV&-lE>-VkF0lmm+w^$0qr>d!|fX!bj`X z^g;L}z#eR`#vbtUYZdU8g$D{5iFFCIW=a=dg_fOfnwH9B&3XbNX>h)Ubx5FQrZ*5{12Md5VnlBPgZ$Na z0Sr&e%LCS4PN;tks~l2^)BO9ADSI)NVX8_%9O4} z9p)kot&yVO3z3l$qwNWDsTT`D?84>E-+~C~bQIyW@~S|*8I&)<|EBRAtenS9YZuPa z(z!ujepoxsA))7BYBSGa5hnVvrMT^Cc=7l#t>bUQt$Y)~D!mo=FjkdY8?4X#GoIk; z$7AwU*~n)G4n=rZob0cD+KA$#Dvrvnqw9y66DJtaHDgd6-lwg8BJ_TWM`yF?W_&hg zp`j6T#$f0WKi-fVMzC()=y(lO5BZJRn=7~4>jP1rcpDTa`LV(Kz9^JFO9*sV>Qd-l zuD$-qxV~uYV&i(eExl{QhCi8N%X^roccLeS&zsx zzW%;5c{|Q5r49qG`UjJ>tqmq?s(R*f(^H#yL1;3RWtqP+Q;E+u?c}O}`@55Hdd)QE z3_|nLQ!=FsuEdB~RN=>0oW8ngf z!J0hl0@Q|YaepW2fvN;F2X0)9JZT>+)bT41P%5ZI|C1$j<>6$o3J+t7_3Vn3X22Ie2W14yA3d?f%uL1;KB|gGK1E2e_=rZ zR^U`xj-WnCzWypIQSv;1G5RD^`qJezM(}Zp=Pu^m2ux!=?ogX)%*MjK_(VM6{N$gU zm^5lGz-)DlJ(l5%NPA~jZ8uf9y#XO_kTL+~1YqZAmjf2Q2k}nQvkBBkWRgP!V@#ty ziSwn1kxRu3wM4fEmsTbk+IAaJP8nv~d-7WcoCHi%C4vjMhHoy1PJ& zt`Vg@V=RI#hi{&-Z!$j2v(Gf@(4)sv|AWNb@y1}SsyQ1TBGOL71zHox?+D_>jz>g& znbMEQHA~Gm5QWIdCi%l79KmZ-FXHw9)gpeQY7W3gyR+4Y?oR*K&Q7zY2BS@db-#C* zljVUL3ti8s4SULX8-@k+5CI#ZitpoWDj%qgJ9&=^gf!HeDc97(yBjsN}_n-*j z=Thr%XZydVnDJFtjcDf@Nf_&87g~8mJAz<5hxv?IxgA&j@V+_cehKdRNW4YieNit1 zKVd<5D$0G~(eY;s7W)T?b?o)5I02#CV^k%^z1x-_$uJpNhbqi!Nl9pH>TcA-^+;sz zMMjk0x{mB!DSZ#s-0IwNqw>Ve-^A&^g?tvh;+F$nK?R&=Tg0nxxM`K|bHWb^vo~-N zJe)k6Xa<{c`T{@|3oH@dgC8+u)LFq;GOlnb#OwagR6fhe%ZCdpA}ben80%+_!}iD5 zjkRk~vA@UetKYbHWO->W&DFi3XH$YOWDi}id!y5cz83^Bx%}uiA{!T>-t75FRljG& zsd;?-WckFJJC(u==*itq3)TGe;Y3)3k}W zv)Bk0Klncw;OozHFE*}&pAnqQ=f%c$+`rh1lPC~F+X?&8W*TiDv#|rwb}PldA8i)Y zL#J&nnWED+8^vwft^qB$pEsU_&EKD}A8~wPY3PG`UwdGB0&w-pj7ZA?iMsp%M4faX zqAGKUTK`i?6oQJu$v?qEKDVMjAyJt0Xxft1#R#o%{kT#{EMJs=#QR_U#;sq*%TB2Z z$O%2ELQn3e)*Xnmt^;=B6Alth>c64Hbk1&Nw0Bg+@ak_F-b6Lp>I=2k{~Z#dYuQEY ziPoNVp!O^l=Qu(z5qCM{*xm`OfZ)=-M+DW`S$!Z7S4 z0%|9FQ}@wD676_NT24EoorU9NW}PCt*-77qaL_;5ET-|iW=-oET3{2aBO`itUh|kc z#iH{8FTZ-3@@5H`q7h)L!5?wR%5U*BxzV;0O4kE^VP>fF`ciMxuNKr-?q66?W|RB* zCr}aPg&1x3qMF!U-p!~eTU%A?C)wH_pt2O=1-2KIgJ@UoxcXn<1@r~H_$FGW@f52A z%&z>PoCzYu|qB3CaYM<=;}j!?4L;zZ_`x zj!PedUO*?9jx1fc;L|p8vf)HTJlQxRm`hL95j=v*$SEjw8iu8qp&u9Xa%v-zA%o|c z&4?D!xWXG`4Q7mA6I#Jf=qxAAEKYY{e54{ie+<^kIL1(f)y)Vd@V3RM_aS>`X)x~X zH6p`Tq86OauuuutXCH>1qANs_V3S}|9uW7*`ai;6{12z0SP|Z}ucJRw$MpB=e1CR!J5kb=Hz0#w zWkqQ20oBrL$wzAtP;A?+P7@Dah;>>NYZmdTBG{Uy(eku9(Jg|&fVT=nVynW79l?d( zW;(-5D&OO`H9YC*+WJgJ8iNNl#PDSUx}&Ab&`O~CA3?mtki>GNI1u-aMcgx1#P>>q z1_B3fXTO&=n#?;$#kyZo`!Go?qO&h#5{zlD)alH>_> zr2msMO%)!!UR2>${T#+p$QOm9{)n&z*t!L)P4lae0F)y*E>rpxa)enC^KgtXM_JIF zo9EZaqmCWW*`@X=)f&KcpLBv5F-w4J0qf_|RKaw~v3I8$i>esL;-KIzbez>#k9ddp zjQqo5tfHKH?xyBKv4%zd3*ZG@F9*s;#_Dlg+PIhj`s5bZ+r4GD22h~~SL-fsIbqw% zJ@P&WOP}G6iezI(RDAA*&n(Vo4>Xz24)yHDGiG?X%E8U;q9=BYwC+l6C@8>!7C(}ygaK?X=y4{G2~m@&q7rob=8`|)>)!70|2Pa_`# z-nH8?*nck`9>65*pe7s9k6DYd6v^L#r@2+adqkBfIx&cU#ZS4Q0y2!3o`_5G=!Zox z-oHT-;0P-bl5+`QV$q1Jz1F2@hLmW8=4M2U9?~vAdKT6-CM| zD&%HDU_x$>@uZG&jaUkge@h*-cpjO`@kqNT!}UK zm8?j&zi=RtrdQbZn;OMZW?b5H!|iiHNzF3oWn(#hHB||v#vl{wNGDDxs88P9qMTh&^g7 zD<8yn5;32N@0GxJ@fd6WyA`m3J@*J( z3I9SpH>>>YKl8V%{3GI-Ru_dGEF`8YJh;R|)XTrS$V9h#Zc#OtspljZ$0^^#=S5L` zv`@AW<`vU@GkTx`KTB|n{m;fcjYDXG(lVl!^3WwO@ATpYZBTQU7qNE-X3?nkX3`q@ zw0QY>2xEVCE@u}^4S0`5p2aqME)G6Zf7r!AC!+nv+G2Q}{%c-q!V%jp>NvOP=AMlk zhH;()d-1IS)bjx9N#C@%1B+m;J?%yCr6s+gpRlpu4{iAx>wU#DHyGc0gzhX-jA)24 zN=R8y9O*3viW79HMz}d6#~INJko+in9~n6wEzLtqM)X_fU{u|4E*wurXBnu7dKLJ z=AlI5^PJGC5$0NyTI@HjL-_IX;ndMr6g>?YYn^ zTs@Vg?f?q=O)GN8GGwqj2RlI4npUl3RRZ}A*vWIqDnD7}6ck89fY9ax_-Y$Wf(UY! z(a5v^=_;9ylh3z{bZh|d%rgQI=~59x7Wb4aOCyyQNm7D&i4ZkUbjH?9jDZ1?iUf*J zs4nhBzu9MWDLY~*eQJRip_mo;3^kX=8MA_V?i5{ztE8R>@r)jFzMkSU*^&<_Fo+qf zB2CgT(c1t2Bw6RU$Y4xY49$6UVq9Uj> zHz5%GlY0?MkV^tM%TC;ly|47K_I?`_h|T-sbFo%~am77N4jF^6-No1A5mfV$R0pab z5&k%XCgk-x=32WJg_u%~t8v>_k`IrUeaFiQ$zSnf%hVGw`J#<(6rvZ~g)6>Z3A=@y z_=07fw~!EO?Y7 zP;-UXV?^H~OYmRas~q&Ty2IxjwwqidAyd+rxS@Tf{-fobxmO%+vgAw8%IW$4DL! z8O@rh2jTl#U@*T5j?<5r{|*{4V>i1-GNmPRxkHp{u>OIy=!O*k-ijGJ562+SFGHYQ zJcZmib5foueRU4cK^kr2fP%BLtMDt}ZNx{G`|;6jeE$u83AqJ{lDT9w_$~!Nae9!L z+6FYc-Zk3(3y(b3d>n=m%fe9^K|y>V3L&fTBT|cvwg|Fugs=+M&ntgKylNb>+7cJT zh?y`xZ8!DOBT``grKXK+$geW{*=QpN~JH+A05)l2(!63UsxfAJg z)%bE!Gb$+k7&I15Qt9XgPzk{u=$z2J7BOidABBkB7erZ+p{ESLXo9Hc|YU1 zwchM)6`sXMUzfVc{LI?UE50^!KBlv8&ciD|9srrr=jxSx{`yi@fpcSs8=Qe5HWAPM zE#o1vjQmdMUoh1=8mg~qHg3BGcSyr;M~dHeS==GZG>?{%8GnF5t}&KD z8O%v1O3S_98&L&5d4r$7@Yi4Y>tX&9o59~kYHA@{$s1f zGgaV0p@6%R4X5ZtzY0C`SHEhsoeNUnxx$NHL+(;SFYzOS@gltcJc#$72Qek}AQOKK zoI3CsKgRpdpB9Uk7fs{LK{Gz}6;i`jpZUhKb-y=(N8yL@ic!&ztB?!qV}gSK-#KKS z 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⪼I^9 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

%iGt#JS^Qcxg3h*hEOef>2> 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�%!2BFn@uQz(Vaqb}zVNsx%Q_6<*0V_KJF0Hqg_*00xh!Pk#%47=(^q)A z9pctI*k7pQ_;8AM0MCY~C)q>+FoCFTve6J=GmG6|T@5ISlf%If{$_eJtLaO#{uyyK z`!nni_}Cg3_NLLIY?iR3X{q*5kn-LY|I?}%Vnn$0dCD)`nR*G#M`R{~A~(Tq%cJS9 zH#LIoJ{YB4<;TqWByz<{0te6wAf?Zv(ZxnN##>+arJ1SmsGY6(DMkHIKlJ|cWBNmA z;Amgqn*6j zTqNq@=;nj$`Zo}l&@I2D+0P490Nx}L8f1rVdL3FJ^kr7u-vt0wpbv&1;wbdbK^cOA z;inCgSJC40C81GiFLuC++x&T%QMAQbUG-yMQ4Y9EDlb~lizDnoy_mA3RQtI)sHME# zMEwAINIq)RskLH?hWsG0HTGrntG&g??y%1R-HDxtUM|80odEAO0wPoY85wqBSsU5H z0?KUY>(~x9e*;BW_Xy^+=z^&GV05+u(@+CuCQ*HeNL4%d4jaM3gZJ*mumc>lI%LA7 z9e{46VS#$z3iy!~);9kLLA^7A(aPz*D^p+uDv$C+8>5$Eb!zMVtu4X=TCIYH_gA8; zLu*=qb3-Z4)kI$12~M}R1v@KEn!VmB?(ofaYZ2|9*rQ(pJ*hes^!SMMclukGdOA6M z1p~b{-V}pOAOcT1wrMFQ40`~Oe&lpld8@m8>u(b%ru*rhLVQJ9qo`Qz8`^F_ZBOWk z*)W|#%JWf?5g3K|;LnIG{5rG|Hu_e9$R-D7nj><_fq`a3J~^hs;ULF!I53LvA)*nb z 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
li?ZgmFk$FZjq0UHXPi)4E24OE%U;{=+G6#_-LB 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
S4!DNl1WsjgBzDF$v5(n&x# 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 literal 0 HcmV?d00001 diff --git a/posthog/user_scripts/aggregate_funnel.py b/posthog/user_scripts/aggregate_funnel.py deleted file mode 100755 index 1c40a993f91df..0000000000000 --- a/posthog/user_scripts/aggregate_funnel.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/python3 -import json -import sys -from dataclasses import dataclass, replace -from itertools import groupby, permutations -from typing import Any, cast -from collections.abc import Sequence - - -def parse_args(line): - args = json.loads(line) - return [ - int(args["num_steps"]), - int(args["conversion_window_limit"]), - str(args["breakdown_attribution_type"]), - str(args["funnel_order_type"]), - args["prop_vals"], # Array(Array(String)) - args["value"], # Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) - ] - - -@dataclass(frozen=True) -class EnteredTimestamp: - timestamp: Any - timings: Any - uuids: list[str] - - -MAX_REPLAY_EVENTS = 10 - - -# each one can be multiple steps here -# it only matters when they entered the funnel - you can propagate the time from the previous step when you update -# This function is defined for Clickhouse in user_defined_functions.xml along with types -# num_steps is the total number of steps in the funnel -# conversion_window_limit is in seconds -# events is an array of tuples of (timestamp, breakdown, [steps]) -# steps is an array of integers which represent the steps that this event qualifies for. it looks like [1,3,5,6]. -# negative integers represent an exclusion on that step. each event is either all exclusions or all steps. -def calculate_funnel_from_user_events( - num_steps: int, - conversion_window_limit_seconds: int, - breakdown_attribution_type: str, - funnel_order_type: str, - prop_vals: list[Any], - events: Sequence[tuple[float, str, list[str] | int | str, list[int]]], -): - default_entered_timestamp = EnteredTimestamp(0, [], []) - max_step = [0, default_entered_timestamp] - # If the attribution mode is a breakdown step, set this to the integer that represents that step - breakdown_step = int(breakdown_attribution_type[5:]) if breakdown_attribution_type.startswith("step_") else None - - # This function returns an Array. We build up an array of strings to return here. - results: list[tuple[int, Any, list[float], list[list[str]]]] = [] - - # Process an event. If this hits an exclusion, return False, else return True. - def process_event(timestamp, uuid, breakdown, steps, *, entered_timestamp, prop_val, event_uuids) -> bool: - # iterate the steps in reverse so we don't count this event multiple times - for step in reversed(steps): - exclusion = False - if step < 0: - exclusion = True - step = -step - - in_match_window = timestamp - entered_timestamp[step - 1].timestamp <= conversion_window_limit_seconds - already_reached_this_step_with_same_entered_timestamp = ( - entered_timestamp[step].timestamp == entered_timestamp[step - 1].timestamp - and entered_timestamp[step].timestamp != 0 - ) - - if in_match_window and not already_reached_this_step_with_same_entered_timestamp: - if exclusion: - results.append((-1, prop_val, [], [])) - return False - is_unmatched_step_attribution = ( - breakdown_step is not None and step == breakdown_step - 1 and prop_val != breakdown - ) - if not is_unmatched_step_attribution: - entered_timestamp[step] = replace( - entered_timestamp[step - 1], - timings=[*entered_timestamp[step - 1].timings, timestamp], - uuids=[*entered_timestamp[step - 1].uuids, uuid], - ) - if len(event_uuids[step - 1]) < MAX_REPLAY_EVENTS - 1: - event_uuids[step - 1].append(uuid) - # TODO: If this is strict, and this didn't match, we should remove this - if step > max_step[0]: - max_step[:] = (step, entered_timestamp[step]) - - if funnel_order_type == "strict": - for i in range(1, len(entered_timestamp)): - if i not in steps: - entered_timestamp[i] = default_entered_timestamp - - return True - - # We call this for each possible breakdown value. - def loop_prop_val(prop_val): - # an array of when the user entered the funnel - # entered_timestamp = [(0, "", [])] * (num_steps + 1) - max_step[:] = [0, default_entered_timestamp] - entered_timestamp: list[EnteredTimestamp] = [default_entered_timestamp] * (num_steps + 1) - event_uuids: list[list[str]] = [[] for _ in range(num_steps)] - - def add_max_step(): - final_index = cast(int, max_step[0]) - final = cast(EnteredTimestamp, max_step[1]) - for i in range(final_index): - # if len(event_uuids[i]) >= MAX_REPLAY_EVENTS and final.uuids[i] not in event_uuids[i]: - # Always put the actual event uuids first, we use it to extract timestamps - # This might create duplicates, but that's fine (we can remove it in clickhouse) - event_uuids[i].insert(0, final.uuids[i]) - results.append( - ( - final_index - 1, - prop_val, - [final.timings[i] - final.timings[i - 1] for i in range(1, final_index)], - event_uuids, - ) - ) - - filtered_events = ( - ( - (timestamp, uuid, breakdown, steps) - for (timestamp, uuid, breakdown, steps) in events - if breakdown == prop_val - ) - if breakdown_attribution_type == "all_events" - else events - ) - for timestamp, events_with_same_timestamp_iterator in groupby(filtered_events, key=lambda x: x[0]): - events_with_same_timestamp = tuple(events_with_same_timestamp_iterator) - entered_timestamp[0] = EnteredTimestamp(timestamp, [], []) - if len(events_with_same_timestamp) == 1: - if not process_event( - *events_with_same_timestamp[0], - entered_timestamp=entered_timestamp, - prop_val=prop_val, - event_uuids=event_uuids, - ): - return - else: - # This is a special case for events with the same timestamp - # We play all of their permutations and most generously take the ones that advanced the furthest - # This has quite bad performance, and can probably be optimized through clever but annoying logic - # but shouldn't be hit too often - # This could potentially cause the same event to be added to the matching events multiple times - entered_timestamps = [] - for events_group_perm in permutations(events_with_same_timestamp): - entered_timestamps.append(list(entered_timestamp)) - for event in events_group_perm: - if not process_event( - *event, entered_timestamp=entered_timestamps[-1], prop_val=prop_val, event_uuids=event_uuids - ): - # If any of the permutations hits an exclusion, we exclude this user. - # This isn't an important implementation detail and we could do something smarter here. - return - for i in range(len(entered_timestamp)): - entered_timestamp[i] = max((x[i] for x in entered_timestamps), key=lambda x: x.timestamp) - - # If we have hit the goal, we can terminate early - if entered_timestamp[num_steps].timestamp > 0: - add_max_step() - return - - # Find the furthest step we have made it to and print it - add_max_step() - return - - [loop_prop_val(prop_val) for prop_val in prop_vals] - print(json.dumps({"result": results}), end="\n") # noqa: T201 - - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/aggregate_funnel_array.py b/posthog/user_scripts/aggregate_funnel_array.py deleted file mode 100755 index 17b053bb7d448..0000000000000 --- a/posthog/user_scripts/aggregate_funnel_array.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel import parse_args, calculate_funnel_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/aggregate_funnel_cohort.py b/posthog/user_scripts/aggregate_funnel_cohort.py deleted file mode 100755 index 17b053bb7d448..0000000000000 --- a/posthog/user_scripts/aggregate_funnel_cohort.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel import parse_args, calculate_funnel_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/aggregate_funnel_test.py b/posthog/user_scripts/aggregate_funnel_test.py index 3eff43269c58e..1eae7c9f36914 100755 --- a/posthog/user_scripts/aggregate_funnel_test.py +++ b/posthog/user_scripts/aggregate_funnel_test.py @@ -1,14 +1,14 @@ #!/usr/bin/python3 import json -from aggregate_funnel import calculate_funnel_from_user_events, parse_args import sys import traceback if __name__ == "__main__": for line in sys.stdin: try: - calculate_funnel_from_user_events(*parse_args(line)) + # calculate_funnel_from_user_events(*parse_args(line)) + print(json.dumps({"result": line})) # noqa: T201 except Exception as e: print(json.dumps({"result": json.dumps(str(e) + traceback.format_exc())}), end="\n") # noqa: T201 sys.stdout.flush() diff --git a/posthog/user_scripts/latest_user_defined_function.xml b/posthog/user_scripts/latest_user_defined_function.xml index cec2d0d340802..8aa8449bf1a54 100644 --- a/posthog/user_scripts/latest_user_defined_function.xml +++ b/posthog/user_scripts/latest_user_defined_function.xml @@ -1,9 +1,9 @@ - executable aggregate_funnel - Array(Tuple(Int8, Nullable(String), Array(Float64))) + Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -26,17 +26,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow - aggregate_funnel.py + aggregate_funnel + 600 executable aggregate_funnel_cohort - Array(Tuple(Int8, UInt64, Array(Float64))) + Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) result UInt8 @@ -59,17 +60,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) value JSONEachRow - aggregate_funnel_cohort.py + aggregate_funnel + 600 executable aggregate_funnel_array - Array(Tuple(Int8, Array(String), Array(Float64))) + Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -92,11 +94,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) value JSONEachRow - aggregate_funnel_array.py + aggregate_funnel + 600 @@ -125,11 +128,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow aggregate_funnel_test.py + 600 @@ -171,6 +175,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_trends.py + 600 @@ -209,6 +214,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_array_trends.py + 600 @@ -247,6 +253,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_cohort_trends.py + 600 @@ -284,11 +291,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_array_trends_test.py + 600 executable aggregate_funnel_v0 - Array(Tuple(Int8, Nullable(String), Array(Float64))) + Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -311,17 +319,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow - v0/aggregate_funnel.py + v0/aggregate_funnel + 600 executable aggregate_funnel_cohort_v0 - Array(Tuple(Int8, UInt64, Array(Float64))) + Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) result UInt8 @@ -344,17 +353,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) value JSONEachRow - v0/aggregate_funnel_cohort.py + v0/aggregate_funnel + 600 executable aggregate_funnel_array_v0 - Array(Tuple(Int8, Array(String), Array(Float64))) + Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -377,11 +387,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) value JSONEachRow - v0/aggregate_funnel_array.py + v0/aggregate_funnel + 600 @@ -410,11 +421,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow v0/aggregate_funnel_test.py + 600 @@ -456,6 +468,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_trends.py + 600 @@ -494,6 +507,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_array_trends.py + 600 @@ -532,6 +546,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_cohort_trends.py + 600 @@ -569,290 +584,6 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_array_trends_test.py - - - executable - aggregate_funnel_v1 - Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel.py - - - - executable - aggregate_funnel_cohort_v1 - Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_cohort.py - - - - executable - aggregate_funnel_array_v1 - Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_array.py - - - - executable - aggregate_funnel_test_v1 - String - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_test.py - - - - executable - aggregate_funnel_trends_v1 - Array(Tuple(DateTime, Int8, Nullable(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Nullable(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_trends.py - - - - executable - aggregate_funnel_array_trends_v1 - - Array(Tuple(DateTime, Int8, Array(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_array_trends.py - - - - executable - aggregate_funnel_cohort_trends_v1 - - Array(Tuple(DateTime, Int8, UInt64)) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), UInt64, Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_cohort_trends.py - - - - executable - aggregate_funnel_array_trends_test_v1 - String - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_array_trends_test.py + 600 \ No newline at end of file diff --git a/posthog/user_scripts/v0/aggregate_funnel b/posthog/user_scripts/v0/aggregate_funnel new file mode 100755 index 0000000000000000000000000000000000000000..04454c7371931d255eb56fb38e3c04159c329622 GIT binary patch literal 680624 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

e`xXYj1kcj542upFh@b2-GksWe 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 z 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⪼I^9 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

%iGt#JS^Qcxg3h*hEOef>2> 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�%!2BFn@uQz(Vaqb}zVNsx%Q_6<*0V_KJF0Hqg_*00xh!Pk#%47=(^q)A z9pctI*k7pQ_;8AM0MCY~C)q>+FoCFTve6J=GmG6|T@5ISlf%If{$_eJtLaO#{uyyK z`!nni_}Cg3_NLLIY?iR3X{q*5kn-LY|I?}%Vnn$0dCD)`nR*G#M`R{~A~(Tq%cJS9 zH#LIoJ{YB4<;TqWByz<{0te6wAf?Zv(ZxnN##>+arJ1SmsGY6(DMkHIKlJ|cWBNmA z;Amgqn*6j zTqNq@=;nj$`Zo}l&@I2D+0P490Nx}L8f1rVdL3FJ^kr7u-vt0wpbv&1;wbdbK^cOA z;inCgSJC40C81GiFLuC++x&T%QMAQbUG-yMQ4Y9EDlb~lizDnoy_mA3RQtI)sHME# zMEwAINIq)RskLH?hWsG0HTGrntG&g??y%1R-HDxtUM|80odEAO0wPoY85wqBSsU5H z0?KUY>(~x9e*;BW_Xy^+=z^&GV05+u(@+CuCQ*HeNL4%d4jaM3gZJ*mumc>lI%LA7 z9e{46VS#$z3iy!~);9kLLA^7A(aPz*D^p+uDv$C+8>5$Eb!zMVtu4X=TCIYH_gA8; zLu*=qb3-Z4)kI$12~M}R1v@KEn!VmB?(ofaYZ2|9*rQ(pJ*hes^!SMMclukGdOA6M z1p~b{-V}pOAOcT1wrMFQ40`~Oe&lpld8@m8>u(b%ru*rhLVQJ9qo`Qz8`^F_ZBOWk z*)W|#%JWf?5g3K|;LnIG{5rG|Hu_e9$R-D7nj><_fq`a3J~^hs;ULF!I53LvA)*nb z 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
li?ZgmFk$FZjq0UHXPi)4E24OE%U;{=+G6#_-LB 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
S4!DNl1WsjgBzDF$v5(n&x# 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 literal 0 HcmV?d00001 diff --git a/posthog/user_scripts/v0/aggregate_funnel.py b/posthog/user_scripts/v0/aggregate_funnel.py deleted file mode 100755 index 162918a819625..0000000000000 --- a/posthog/user_scripts/v0/aggregate_funnel.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/python3 -import json -import sys -from dataclasses import dataclass, replace -from itertools import groupby, permutations -from typing import Any, cast -from collections.abc import Sequence - - -def parse_args(line): - args = json.loads(line) - return [ - int(args["num_steps"]), - int(args["conversion_window_limit"]), - str(args["breakdown_attribution_type"]), - str(args["funnel_order_type"]), - args["prop_vals"], # Array(Array(String)) - args["value"], # Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - ] - - -@dataclass(frozen=True) -class EnteredTimestamp: - timestamp: Any - timings: Any - - -# each one can be multiple steps here -# it only matters when they entered the funnel - you can propagate the time from the previous step when you update -# This function is defined for Clickhouse in user_defined_functions.xml along with types -# num_steps is the total number of steps in the funnel -# conversion_window_limit is in seconds -# events is a array of tuples of (timestamp, breakdown, [steps]) -# steps is an array of integers which represent the steps that this event qualifies for. it looks like [1,3,5,6]. -# negative integers represent an exclusion on that step. each event is either all exclusions or all steps. -def calculate_funnel_from_user_events( - num_steps: int, - conversion_window_limit_seconds: int, - breakdown_attribution_type: str, - funnel_order_type: str, - prop_vals: list[Any], - events: Sequence[tuple[float, list[str] | int | str, list[int]]], -): - default_entered_timestamp = EnteredTimestamp(0, []) - max_step = [0, default_entered_timestamp] - # If the attribution mode is a breakdown step, set this to the integer that represents that step - breakdown_step = int(breakdown_attribution_type[5:]) if breakdown_attribution_type.startswith("step_") else None - - # This function returns an Array. We build up an array of strings to return here. - results: list[tuple[int, Any, list[float]]] = [] - - # Process an event. If this hits an exclusion, return False, else return True. - def process_event(timestamp, breakdown, steps, *, entered_timestamp, prop_val) -> bool: - # iterate the steps in reverse so we don't count this event multiple times - for step in reversed(steps): - exclusion = False - if step < 0: - exclusion = True - step = -step - - in_match_window = timestamp - entered_timestamp[step - 1].timestamp <= conversion_window_limit_seconds - already_reached_this_step_with_same_entered_timestamp = ( - entered_timestamp[step].timestamp == entered_timestamp[step - 1].timestamp - ) - - if in_match_window and not already_reached_this_step_with_same_entered_timestamp: - if exclusion: - results.append((-1, prop_val, [])) - return False - is_unmatched_step_attribution = ( - breakdown_step is not None and step == breakdown_step - 1 and prop_val != breakdown - ) - if not is_unmatched_step_attribution: - entered_timestamp[step] = replace( - entered_timestamp[step - 1], timings=[*entered_timestamp[step - 1].timings, timestamp] - ) - if step > max_step[0]: - max_step[:] = (step, entered_timestamp[step]) - - if funnel_order_type == "strict": - for i in range(len(entered_timestamp)): - if i not in steps: - entered_timestamp[i] = default_entered_timestamp - - return True - - # We call this for each possible breakdown value. - def loop_prop_val(prop_val): - # an array of when the user entered the funnel - # entered_timestamp = [(0, "", [])] * (num_steps + 1) - max_step[:] = [0, default_entered_timestamp] - entered_timestamp: list[EnteredTimestamp] = [default_entered_timestamp] * (num_steps + 1) - - def add_max_step(): - i = cast(int, max_step[0]) - final = cast(EnteredTimestamp, max_step[1]) - results.append((i - 1, prop_val, [final.timings[i] - final.timings[i - 1] for i in range(1, i)])) - - filtered_events = ( - ((timestamp, breakdown, steps) for (timestamp, breakdown, steps) in events if breakdown == prop_val) - if breakdown_attribution_type == "all_events" - else events - ) - for timestamp, events_with_same_timestamp_iterator in groupby(filtered_events, key=lambda x: x[0]): - events_with_same_timestamp = tuple(events_with_same_timestamp_iterator) - entered_timestamp[0] = EnteredTimestamp(timestamp, []) - if len(events_with_same_timestamp) == 1: - if not process_event( - *events_with_same_timestamp[0], entered_timestamp=entered_timestamp, prop_val=prop_val - ): - return - else: - # This is a special case for events with the same timestamp - # We play all of their permutations and most generously take the ones that advanced the furthest - # This has quite bad performance, and can probably be optimized through clever but annoying logic - # but shouldn't be hit too often - entered_timestamps = [] - for events_group_perm in permutations(events_with_same_timestamp): - entered_timestamps.append(list(entered_timestamp)) - for event in events_group_perm: - if not process_event(*event, entered_timestamp=entered_timestamps[-1], prop_val=prop_val): - # If any of the permutations hits an exclusion, we exclude this user. - # This isn't an important implementation detail and we could do something smarter here. - return - for i in range(len(entered_timestamp)): - entered_timestamp[i] = max((x[i] for x in entered_timestamps), key=lambda x: x.timestamp) - - # If we have hit the goal, we can terminate early - if entered_timestamp[num_steps].timestamp > 0: - add_max_step() - return - - # Find the furthest step we have made it to and print it - add_max_step() - return - - [loop_prop_val(prop_val) for prop_val in prop_vals] - print(json.dumps({"result": results}), end="\n") # noqa: T201 - - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v0/aggregate_funnel_array.py b/posthog/user_scripts/v0/aggregate_funnel_array.py deleted file mode 100755 index 17b053bb7d448..0000000000000 --- a/posthog/user_scripts/v0/aggregate_funnel_array.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel import parse_args, calculate_funnel_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v0/aggregate_funnel_cohort.py b/posthog/user_scripts/v0/aggregate_funnel_cohort.py deleted file mode 100755 index 17b053bb7d448..0000000000000 --- a/posthog/user_scripts/v0/aggregate_funnel_cohort.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel import parse_args, calculate_funnel_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v0/aggregate_funnel_test.py b/posthog/user_scripts/v0/aggregate_funnel_test.py index e0689b82af21c..1eae7c9f36914 100755 --- a/posthog/user_scripts/v0/aggregate_funnel_test.py +++ b/posthog/user_scripts/v0/aggregate_funnel_test.py @@ -1,13 +1,14 @@ #!/usr/bin/python3 import json -from aggregate_funnel import calculate_funnel_from_user_events, parse_args import sys +import traceback if __name__ == "__main__": for line in sys.stdin: try: - calculate_funnel_from_user_events(*parse_args(line)) + # calculate_funnel_from_user_events(*parse_args(line)) + print(json.dumps({"result": line})) # noqa: T201 except Exception as e: - print(json.dumps({"result": json.dumps(str(e))}), end="\n") # noqa: T201 + print(json.dumps({"result": json.dumps(str(e) + traceback.format_exc())}), end="\n") # noqa: T201 sys.stdout.flush() diff --git a/posthog/user_scripts/v0/user_defined_function.xml b/posthog/user_scripts/v0/user_defined_function.xml index 6f8f787da15c1..8aa8449bf1a54 100644 --- a/posthog/user_scripts/v0/user_defined_function.xml +++ b/posthog/user_scripts/v0/user_defined_function.xml @@ -1,9 +1,9 @@ - executable aggregate_funnel - Array(Tuple(Int8, Nullable(String), Array(Float64))) + Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -26,17 +26,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow - aggregate_funnel.py + aggregate_funnel + 600 executable aggregate_funnel_cohort - Array(Tuple(Int8, UInt64, Array(Float64))) + Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) result UInt8 @@ -59,17 +60,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) value JSONEachRow - aggregate_funnel_cohort.py + aggregate_funnel + 600 executable aggregate_funnel_array - Array(Tuple(Int8, Array(String), Array(Float64))) + Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -92,11 +94,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) value JSONEachRow - aggregate_funnel_array.py + aggregate_funnel + 600 @@ -125,11 +128,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow aggregate_funnel_test.py + 600 @@ -171,6 +175,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_trends.py + 600 @@ -209,6 +214,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_array_trends.py + 600 @@ -247,6 +253,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_cohort_trends.py + 600 @@ -284,11 +291,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow aggregate_funnel_array_trends_test.py + 600 executable aggregate_funnel_v0 - Array(Tuple(Int8, Nullable(String), Array(Float64))) + Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -311,17 +319,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow - v0/aggregate_funnel.py + v0/aggregate_funnel + 600 executable aggregate_funnel_cohort_v0 - Array(Tuple(Int8, UInt64, Array(Float64))) + Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) result UInt8 @@ -344,17 +353,18 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) value JSONEachRow - v0/aggregate_funnel_cohort.py + v0/aggregate_funnel + 600 executable aggregate_funnel_array_v0 - Array(Tuple(Int8, Array(String), Array(Float64))) + Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) result UInt8 @@ -377,11 +387,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) value JSONEachRow - v0/aggregate_funnel_array.py + v0/aggregate_funnel + 600 @@ -410,11 +421,12 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the prop_vals - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) + Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) value JSONEachRow v0/aggregate_funnel_test.py + 600 @@ -456,6 +468,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_trends.py + 600 @@ -494,6 +507,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_array_trends.py + 600 @@ -532,6 +546,7 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_cohort_trends.py + 600 @@ -569,5 +584,6 @@ This file is autogenerated by udf_versioner.py. Do not edit this, only edit the JSONEachRow v0/aggregate_funnel_array_trends_test.py + 600 \ No newline at end of file diff --git a/posthog/user_scripts/v1/aggregate_funnel.py b/posthog/user_scripts/v1/aggregate_funnel.py deleted file mode 100755 index 1c40a993f91df..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/python3 -import json -import sys -from dataclasses import dataclass, replace -from itertools import groupby, permutations -from typing import Any, cast -from collections.abc import Sequence - - -def parse_args(line): - args = json.loads(line) - return [ - int(args["num_steps"]), - int(args["conversion_window_limit"]), - str(args["breakdown_attribution_type"]), - str(args["funnel_order_type"]), - args["prop_vals"], # Array(Array(String)) - args["value"], # Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) - ] - - -@dataclass(frozen=True) -class EnteredTimestamp: - timestamp: Any - timings: Any - uuids: list[str] - - -MAX_REPLAY_EVENTS = 10 - - -# each one can be multiple steps here -# it only matters when they entered the funnel - you can propagate the time from the previous step when you update -# This function is defined for Clickhouse in user_defined_functions.xml along with types -# num_steps is the total number of steps in the funnel -# conversion_window_limit is in seconds -# events is an array of tuples of (timestamp, breakdown, [steps]) -# steps is an array of integers which represent the steps that this event qualifies for. it looks like [1,3,5,6]. -# negative integers represent an exclusion on that step. each event is either all exclusions or all steps. -def calculate_funnel_from_user_events( - num_steps: int, - conversion_window_limit_seconds: int, - breakdown_attribution_type: str, - funnel_order_type: str, - prop_vals: list[Any], - events: Sequence[tuple[float, str, list[str] | int | str, list[int]]], -): - default_entered_timestamp = EnteredTimestamp(0, [], []) - max_step = [0, default_entered_timestamp] - # If the attribution mode is a breakdown step, set this to the integer that represents that step - breakdown_step = int(breakdown_attribution_type[5:]) if breakdown_attribution_type.startswith("step_") else None - - # This function returns an Array. We build up an array of strings to return here. - results: list[tuple[int, Any, list[float], list[list[str]]]] = [] - - # Process an event. If this hits an exclusion, return False, else return True. - def process_event(timestamp, uuid, breakdown, steps, *, entered_timestamp, prop_val, event_uuids) -> bool: - # iterate the steps in reverse so we don't count this event multiple times - for step in reversed(steps): - exclusion = False - if step < 0: - exclusion = True - step = -step - - in_match_window = timestamp - entered_timestamp[step - 1].timestamp <= conversion_window_limit_seconds - already_reached_this_step_with_same_entered_timestamp = ( - entered_timestamp[step].timestamp == entered_timestamp[step - 1].timestamp - and entered_timestamp[step].timestamp != 0 - ) - - if in_match_window and not already_reached_this_step_with_same_entered_timestamp: - if exclusion: - results.append((-1, prop_val, [], [])) - return False - is_unmatched_step_attribution = ( - breakdown_step is not None and step == breakdown_step - 1 and prop_val != breakdown - ) - if not is_unmatched_step_attribution: - entered_timestamp[step] = replace( - entered_timestamp[step - 1], - timings=[*entered_timestamp[step - 1].timings, timestamp], - uuids=[*entered_timestamp[step - 1].uuids, uuid], - ) - if len(event_uuids[step - 1]) < MAX_REPLAY_EVENTS - 1: - event_uuids[step - 1].append(uuid) - # TODO: If this is strict, and this didn't match, we should remove this - if step > max_step[0]: - max_step[:] = (step, entered_timestamp[step]) - - if funnel_order_type == "strict": - for i in range(1, len(entered_timestamp)): - if i not in steps: - entered_timestamp[i] = default_entered_timestamp - - return True - - # We call this for each possible breakdown value. - def loop_prop_val(prop_val): - # an array of when the user entered the funnel - # entered_timestamp = [(0, "", [])] * (num_steps + 1) - max_step[:] = [0, default_entered_timestamp] - entered_timestamp: list[EnteredTimestamp] = [default_entered_timestamp] * (num_steps + 1) - event_uuids: list[list[str]] = [[] for _ in range(num_steps)] - - def add_max_step(): - final_index = cast(int, max_step[0]) - final = cast(EnteredTimestamp, max_step[1]) - for i in range(final_index): - # if len(event_uuids[i]) >= MAX_REPLAY_EVENTS and final.uuids[i] not in event_uuids[i]: - # Always put the actual event uuids first, we use it to extract timestamps - # This might create duplicates, but that's fine (we can remove it in clickhouse) - event_uuids[i].insert(0, final.uuids[i]) - results.append( - ( - final_index - 1, - prop_val, - [final.timings[i] - final.timings[i - 1] for i in range(1, final_index)], - event_uuids, - ) - ) - - filtered_events = ( - ( - (timestamp, uuid, breakdown, steps) - for (timestamp, uuid, breakdown, steps) in events - if breakdown == prop_val - ) - if breakdown_attribution_type == "all_events" - else events - ) - for timestamp, events_with_same_timestamp_iterator in groupby(filtered_events, key=lambda x: x[0]): - events_with_same_timestamp = tuple(events_with_same_timestamp_iterator) - entered_timestamp[0] = EnteredTimestamp(timestamp, [], []) - if len(events_with_same_timestamp) == 1: - if not process_event( - *events_with_same_timestamp[0], - entered_timestamp=entered_timestamp, - prop_val=prop_val, - event_uuids=event_uuids, - ): - return - else: - # This is a special case for events with the same timestamp - # We play all of their permutations and most generously take the ones that advanced the furthest - # This has quite bad performance, and can probably be optimized through clever but annoying logic - # but shouldn't be hit too often - # This could potentially cause the same event to be added to the matching events multiple times - entered_timestamps = [] - for events_group_perm in permutations(events_with_same_timestamp): - entered_timestamps.append(list(entered_timestamp)) - for event in events_group_perm: - if not process_event( - *event, entered_timestamp=entered_timestamps[-1], prop_val=prop_val, event_uuids=event_uuids - ): - # If any of the permutations hits an exclusion, we exclude this user. - # This isn't an important implementation detail and we could do something smarter here. - return - for i in range(len(entered_timestamp)): - entered_timestamp[i] = max((x[i] for x in entered_timestamps), key=lambda x: x.timestamp) - - # If we have hit the goal, we can terminate early - if entered_timestamp[num_steps].timestamp > 0: - add_max_step() - return - - # Find the furthest step we have made it to and print it - add_max_step() - return - - [loop_prop_val(prop_val) for prop_val in prop_vals] - print(json.dumps({"result": results}), end="\n") # noqa: T201 - - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_array.py b/posthog/user_scripts/v1/aggregate_funnel_array.py deleted file mode 100755 index 17b053bb7d448..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_array.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel import parse_args, calculate_funnel_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_array_trends.py b/posthog/user_scripts/v1/aggregate_funnel_array_trends.py deleted file mode 100755 index 15e93f5452797..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_array_trends.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel_trends import parse_args, calculate_funnel_trends_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_trends_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_array_trends_test.py b/posthog/user_scripts/v1/aggregate_funnel_array_trends_test.py deleted file mode 100755 index 44d3cc9b8f059..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_array_trends_test.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/python3 - -from aggregate_funnel_trends import calculate_funnel_trends_from_user_events, parse_args -import sys -import json - -if __name__ == "__main__": - for line in sys.stdin: - try: - calculate_funnel_trends_from_user_events(*parse_args(line)) - except Exception as e: - print(json.dumps({"result": json.dumps(str(e))}), end="\n") # noqa: T201 - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_cohort.py b/posthog/user_scripts/v1/aggregate_funnel_cohort.py deleted file mode 100755 index 17b053bb7d448..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_cohort.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel import parse_args, calculate_funnel_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_cohort_trends.py b/posthog/user_scripts/v1/aggregate_funnel_cohort_trends.py deleted file mode 100755 index 15e93f5452797..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_cohort_trends.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python3 -import sys - -from aggregate_funnel_trends import parse_args, calculate_funnel_trends_from_user_events - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_trends_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_test.py b/posthog/user_scripts/v1/aggregate_funnel_test.py deleted file mode 100755 index 3eff43269c58e..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_test.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/python3 -import json - -from aggregate_funnel import calculate_funnel_from_user_events, parse_args -import sys -import traceback - -if __name__ == "__main__": - for line in sys.stdin: - try: - calculate_funnel_from_user_events(*parse_args(line)) - except Exception as e: - print(json.dumps({"result": json.dumps(str(e) + traceback.format_exc())}), end="\n") # noqa: T201 - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/aggregate_funnel_trends.py b/posthog/user_scripts/v1/aggregate_funnel_trends.py deleted file mode 100755 index 0aa96b7a19b96..0000000000000 --- a/posthog/user_scripts/v1/aggregate_funnel_trends.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/python3 -import sys -from dataclasses import dataclass, replace -from typing import Any -from collections.abc import Sequence -import json - - -def parse_args(line): - args = json.loads(line) - return [ - int(args["from_step"]), - int(args["num_steps"]), - int(args["conversion_window_limit"]), - str(args["breakdown_attribution_type"]), - str(args["funnel_order_type"]), - args["prop_vals"], # Array(Array(String)) - args["value"], # Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - ] - - -@dataclass(frozen=True) -class EnteredTimestamp: - timestamp: Any - timings: Any - - -# each one can be multiple steps here -# it only matters when they entered the funnel - you can propagate the time from the previous step when you update -# This function is defined for Clickhouse in user_defined_functions.xml along with types -# num_steps is the total number of steps in the funnel -# conversion_window_limit is in seconds -# events is a array of tuples of (timestamp, breakdown, [steps]) -# steps is an array of integers which represent the steps that this event qualifies for. it looks like [1,3,5,6]. -# negative integers represent an exclusion on that step. each event is either all exclusions or all steps. -def calculate_funnel_trends_from_user_events( - from_step: int, - num_steps: int, - conversion_window_limit_seconds: int, - breakdown_attribution_type: str, - funnel_order_type: str, - prop_vals: list[Any], - events: Sequence[tuple[float, int, list[str] | int | str, list[int]]], -): - default_entered_timestamp = EnteredTimestamp(0, []) - # If the attribution mode is a breakdown step, set this to the integer that represents that step - breakdown_step = int(breakdown_attribution_type[5:]) if breakdown_attribution_type.startswith("step_") else None - - # Results is a map of start intervals to success or failure. If an interval isn't here, it means the - # user didn't enter - results = {} - - # We call this for each possible breakdown value. - def loop_prop_val(prop_val): - # we need to track every distinct entry into the funnel through to the end - filtered_events = ( - ( - (timestamp, interval_start, breakdown, steps) - for (timestamp, interval_start, breakdown, steps) in events - if breakdown == prop_val - ) - if breakdown_attribution_type == "all_events" - else events - ) - list_of_entered_timestamps = [] - - for timestamp, interval_start, breakdown, steps in filtered_events: - for step in reversed(steps): - exclusion = False - if step < 0: - exclusion = True - step = -step - # Special code to handle the first step - # Potential Optimization: we could skip tracking here if the user has already completed the funnel for this interval - if step == 1: - entered_timestamp = [default_entered_timestamp] * (num_steps + 1) - # Set the interval start at 0, which is what we want to return if this works. - # For strict funnels, we need to track if the "from_step" has been hit - # Abuse the timings field on the 0th index entered_timestamp to have the elt True if we have - entered_timestamp[0] = EnteredTimestamp(interval_start, [True] if from_step == 0 else []) - entered_timestamp[1] = EnteredTimestamp(timestamp, [timestamp]) - list_of_entered_timestamps.append(entered_timestamp) - else: - for entered_timestamp in list_of_entered_timestamps[:]: - in_match_window = ( - timestamp - entered_timestamp[step - 1].timestamp <= conversion_window_limit_seconds - ) - already_reached_this_step_with_same_entered_timestamp = ( - entered_timestamp[step].timestamp == entered_timestamp[step - 1].timestamp - ) - if in_match_window and not already_reached_this_step_with_same_entered_timestamp: - if exclusion: - # this is a complete failure, exclude this person, don't print anything, don't count - return False - is_unmatched_step_attribution = ( - breakdown_step is not None and step == breakdown_step - 1 and prop_val != breakdown - ) - if not is_unmatched_step_attribution: - entered_timestamp[step] = replace( - entered_timestamp[step - 1], - timings=[*entered_timestamp[step - 1].timings, timestamp], - ) - # check if we have hit the goal. if we have, remove it from the list and add it to the successful_timestamps - if entered_timestamp[num_steps].timestamp > 0: - results[entered_timestamp[0].timestamp] = (1, prop_val) - list_of_entered_timestamps.remove(entered_timestamp) - # If we have hit the from_step threshold, record it (abuse the timings field) - elif step == from_step + 1: - entered_timestamp[0].timings.append(True) - - # At the end of the event, clear all steps that weren't done by that event - if funnel_order_type == "strict": - for entered_timestamp in list_of_entered_timestamps[:]: - for i in range(1, len(entered_timestamp)): - if i not in steps: - entered_timestamp[i] = default_entered_timestamp - - # At this point, everything left in entered_timestamps is a failure, if it has made it to from_step - for entered_timestamp in list_of_entered_timestamps: - if entered_timestamp[0].timestamp not in results and len(entered_timestamp[0].timings) > 0: - results[entered_timestamp[0].timestamp] = (-1, prop_val) - - [loop_prop_val(prop_val) for prop_val in prop_vals] - result = [(interval_start, success_bool, prop_val) for interval_start, (success_bool, prop_val) in results.items()] - print(json.dumps({"result": result}), end="\n") # noqa: T201 - - -if __name__ == "__main__": - for line in sys.stdin: - calculate_funnel_trends_from_user_events(*parse_args(line)) - sys.stdout.flush() diff --git a/posthog/user_scripts/v1/user_defined_function.xml b/posthog/user_scripts/v1/user_defined_function.xml deleted file mode 100644 index cec2d0d340802..0000000000000 --- a/posthog/user_scripts/v1/user_defined_function.xml +++ /dev/null @@ -1,858 +0,0 @@ - - - executable - aggregate_funnel - Array(Tuple(Int8, Nullable(String), Array(Float64))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) - value - - JSONEachRow - aggregate_funnel.py - - - - executable - aggregate_funnel_cohort - Array(Tuple(Int8, UInt64, Array(Float64))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) - value - - JSONEachRow - aggregate_funnel_cohort.py - - - - executable - aggregate_funnel_array - Array(Tuple(Int8, Array(String), Array(Float64))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) - value - - JSONEachRow - aggregate_funnel_array.py - - - - executable - aggregate_funnel_test - String - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) - value - - JSONEachRow - aggregate_funnel_test.py - - - - executable - aggregate_funnel_trends - Array(Tuple(DateTime, Int8, Nullable(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Nullable(String), Array(Int8))) - value - - JSONEachRow - aggregate_funnel_trends.py - - - - executable - aggregate_funnel_array_trends - - Array(Tuple(DateTime, Int8, Array(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - aggregate_funnel_array_trends.py - - - - executable - aggregate_funnel_cohort_trends - - Array(Tuple(DateTime, Int8, UInt64)) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), UInt64, Array(Int8))) - value - - JSONEachRow - aggregate_funnel_cohort_trends.py - - - - executable - aggregate_funnel_array_trends_test - String - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - aggregate_funnel_array_trends_test.py - - - executable - aggregate_funnel_v0 - Array(Tuple(Int8, Nullable(String), Array(Float64))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel.py - - - - executable - aggregate_funnel_cohort_v0 - Array(Tuple(Int8, UInt64, Array(Float64))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), UInt64, Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_cohort.py - - - - executable - aggregate_funnel_array_v0 - Array(Tuple(Int8, Array(String), Array(Float64))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Array(String), Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_array.py - - - - executable - aggregate_funnel_test_v0 - String - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(String), Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_test.py - - - - executable - aggregate_funnel_trends_v0 - Array(Tuple(DateTime, Int8, Nullable(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Nullable(String), Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_trends.py - - - - executable - aggregate_funnel_array_trends_v0 - - Array(Tuple(DateTime, Int8, Array(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_array_trends.py - - - - executable - aggregate_funnel_cohort_trends_v0 - - Array(Tuple(DateTime, Int8, UInt64)) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), UInt64, Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_cohort_trends.py - - - - executable - aggregate_funnel_array_trends_test_v0 - String - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - v0/aggregate_funnel_array_trends_test.py - - - executable - aggregate_funnel_v1 - Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel.py - - - - executable - aggregate_funnel_cohort_v1 - Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_cohort.py - - - - executable - aggregate_funnel_array_v1 - Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)))) - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_array.py - - - - executable - aggregate_funnel_test_v1 - String - result - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_test.py - - - - executable - aggregate_funnel_trends_v1 - Array(Tuple(DateTime, Int8, Nullable(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Nullable(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Nullable(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_trends.py - - - - executable - aggregate_funnel_array_trends_v1 - - Array(Tuple(DateTime, Int8, Array(String))) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_array_trends.py - - - - executable - aggregate_funnel_cohort_trends_v1 - - Array(Tuple(DateTime, Int8, UInt64)) - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(UInt64) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), UInt64, Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_cohort_trends.py - - - - executable - aggregate_funnel_array_trends_test_v1 - String - result - - UInt8 - from_step - - - UInt8 - num_steps - - - UInt64 - conversion_window_limit - - - String - breakdown_attribution_type - - - String - funnel_order_type - - - Array(Array(String)) - prop_vals - - - Array(Tuple(Nullable(Float64), Nullable(DateTime), Array(String), Array(Int8))) - value - - JSONEachRow - v1/aggregate_funnel_array_trends_test.py - - \ No newline at end of file From e3cfea3117ddeed10795f83746b3845adffa552d Mon Sep 17 00:00:00 2001 From: Sandy Spicer Date: Tue, 1 Oct 2024 15:34:04 -0700 Subject: [PATCH 03/10] remove alpine --- .github/actions/run-backend-tests/action.yml | 2 +- .github/workflows/ci-backend-update-test-timing.yml | 4 ++-- .github/workflows/ci-backend.yml | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/run-backend-tests/action.yml b/.github/actions/run-backend-tests/action.yml index cd632a491c2ab..bde3554bb4e20 100644 --- a/.github/actions/run-backend-tests/action.yml +++ b/.github/actions/run-backend-tests/action.yml @@ -210,7 +210,7 @@ runs: - name: Upload updated timing data as artifacts uses: actions/upload-artifact@v4 - if: ${{ inputs.person-on-events != 'true' && inputs.clickhouse-server-image == 'clickhouse/clickhouse-server:23.12.6.19-alpine' }} + if: ${{ inputs.person-on-events != 'true' && inputs.clickhouse-server-image == 'clickhouse/clickhouse-server:23.12.6.19' }} with: name: timing_data-${{ inputs.segment }}-${{ inputs.group }} path: .test_durations diff --git a/.github/workflows/ci-backend-update-test-timing.yml b/.github/workflows/ci-backend-update-test-timing.yml index 2d722584cc95e..e37df8defe9cb 100644 --- a/.github/workflows/ci-backend-update-test-timing.yml +++ b/.github/workflows/ci-backend-update-test-timing.yml @@ -29,13 +29,13 @@ jobs: group: 1 token: ${{ secrets.POSTHOG_BOT_GITHUB_TOKEN }} python-version: '3.11.9' - clickhouse-server-image: 'clickhouse/clickhouse-server:23.12.6.19-alpine' + clickhouse-server-image: 'clickhouse/clickhouse-server:23.12.6.19' segment: 'FOSS' person-on-events: false - name: Upload updated timing data as artifacts uses: actions/upload-artifact@v4 - if: ${{ inputs.person-on-events != 'true' && inputs.clickhouse-server-image == 'clickhouse/clickhouse-server:23.12.6.19-alpine' }} + if: ${{ inputs.person-on-events != 'true' && inputs.clickhouse-server-image == 'clickhouse/clickhouse-server:23.12.6.19' }} with: name: timing_data-${{ inputs.segment }}-${{ inputs.group }} path: .test_durations diff --git a/.github/workflows/ci-backend.yml b/.github/workflows/ci-backend.yml index cb53aefe20655..56dae66425a29 100644 --- a/.github/workflows/ci-backend.yml +++ b/.github/workflows/ci-backend.yml @@ -240,7 +240,7 @@ jobs: fail-fast: false matrix: python-version: ['3.11.9'] - clickhouse-server-image: ['clickhouse/clickhouse-server:23.12.6.19-alpine'] + clickhouse-server-image: ['clickhouse/clickhouse-server:23.12.6.19'] segment: ['Core'] person-on-events: [false, true] # :NOTE: Keep concurrency and groups in sync @@ -249,7 +249,7 @@ jobs: include: - segment: 'Temporal' person-on-events: false - clickhouse-server-image: 'clickhouse/clickhouse-server:23.12.6.19-alpine' + clickhouse-server-image: 'clickhouse/clickhouse-server:23.12.6.19' python-version: '3.11.9' concurrency: 1 group: 1 @@ -320,7 +320,7 @@ jobs: strategy: fail-fast: false matrix: - clickhouse-server-image: ['clickhouse/clickhouse-server:23.12.6.19-alpine'] + clickhouse-server-image: ['clickhouse/clickhouse-server:23.12.6.19'] if: needs.changes.outputs.backend == 'true' runs-on: ubuntu-latest steps: From 97d1af8532fa2fa3f51d6371fe266e540e61e7c3 Mon Sep 17 00:00:00 2001 From: Alexander Spicer Date: Tue, 1 Oct 2024 22:41:53 -0700 Subject: [PATCH 04/10] glibc instead of musl --- posthog/user_scripts/aggregate_funnel | Bin 680624 -> 572496 bytes posthog/user_scripts/v0/aggregate_funnel | Bin 680624 -> 572496 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/posthog/user_scripts/aggregate_funnel b/posthog/user_scripts/aggregate_funnel index 04454c7371931d255eb56fb38e3c04159c329622..0605040d162ebda124b17c7e9733c137af6e6111 100755 GIT binary patch delta 162193 zcmZ^s30#!L8^_<-mt9bS#bXtfV^vVR5L6To6c2P!OuWep5YJK}0mE}qL?xuCR~@r5 z%t|W{lnk;|%nPj)&#+RlvR=ZJtQ7kv`~S^*EX!NFed3+>`#kf^%rp1A@2-WXJD1nC z&-d=0kjqJ*NcqC$7r7}Rj*H~NIZyoUz_sTLpf0bjZZnkg;$;Q(s_HZBg8yR`x%TQK zN8^0xoy5k?UmfmaEgU5y^~!n4_XHO`3&zU#+G|yzB<0krV?34v&Wq*t-`9HsnPrYs zu2v{Y_Z-74O5r$H323h+!LnXO5BaLb)8UrIt6U++(_T5Iz&^@Vbrs8`3pb79QWRfl zuVxkrAG7qA;~GZfxO^p^_BveAA1&$RnO*7T zYO3&fZ?m6e>CLn$-3Q%Pjj%|}2>Y-IYBdU*bp!PiA#El!)iu{&fk+Oqwk?PLw1@85 z_0A!_EInptwFsFdD{tA^KzrOJ2(_1_`F6I?9vWc}CEG1uv|IVk&Ke=_a=JV1G5Xo{ z4E9jEJydKD&9Ga^x3dV9QFExP3z1CIn)t>_P(RDAIn5s0Y7bqrhg#c1EnrdhLX16! zg?8y)H9h_FcIiXA^fx;jYiFO>*>rp8M|-Fj6viR9^7S2hV!=)}uO-f!omz%p}&Kz!G>YO>x_vy{0rX{9jaH@9doP~3_)CKbr zlhPI>FXrYZElyj=!Op^z#I*Tba>|^=h_Wbs@uI{OZqb}Yi;|bl;TGWrG(J8lBQah{ zHPM)X2xerf6!;2my%kT zoMg{WVp`e~WFNZ8%edJK;}@jOS(2DGCq8BV>?Pd1IcbUM8A}rva*GldvRLu)7y*)y zNa7M}TKuBK1&i&5m>ZIi7TlngRk95mP)~ZETa>aSIc-i-8aJ1D#9p4c3l=9XT(Eo& zH!EpT3QKX$;-y@YoE#j$AamD3)ykYjsdLhh1l>HeaZ@Xov@kgpj$bejR_qD0e6w;b zmVB6$vW(eHdT}=L59cgSjz?J%CI7#;1O=Ar4JpEpsS7gVkt%XDZ!woRD|rc$N=!!z z@zE29Y+>@^Il&VXXDx&k~g| z@rw%<&yF8CCoMWQdhy(3&Vh_a0?CUfz`<#DJb@|F#EFet2Rmp+$J!Of&q+;Rgls5= zhr-=yOA?dj(Bt=Az3JMija$*k$&J0OiX8Svj^|iSvZ1>V3(ZSHt+KmNZsf3G@x6n4 z28T$YUiND*Ze&dK&|&dCgL{VCgQ0!ugT3v+devSI!C-5>Mrgf>UOnsM)hqN24nrTt zpwIr}@xKfHCzx4unCxBgSBLqS{m=e3k~DN&V~H?r^*u?)i-HOTBlS@z{Y?bakxaXDo&Cg|hmx#O?u#UOBQ96DPiwsZ8FJ;e zD)-wYxq*8}xj)42t#IEy1$-uT*%xhI7xz_P0qK{$FlO0?NInX}Ec|T=yY%E~n2G z%#{V>h9@X(V!nn~Dpi@G;U$@}CpLmh?O*MFB}xL@G!afJe2<2^wU7;!Xn2*PU#8(| z!WH#g?tf~+V!c4>eGe2vwHmG(a(lL+tM!p`hRhmnR(SZoxK)l2s}Yn&$$Y*Oo~hxY zqMxtfWQ1&|K*MRY%uB3J1fquLKb8j~x2X+F9HQ_b4UbjUdKL{&QFyGvt!mvrQgW1` ziD0h5?i!y=4evZkE`1p}e7h^Hdg}+_Z)zj#Wx**6>2r z6B@2AVk7^Pqy5GGrvRsb8a{c9T;h#Rc!`E5D4wg(@JvtHqm_)a_ODifnn0~4g37(7 zH}u3`iig5Ayj<}_oQ8WTJi~!Y{VzokWI6~~ovUlNLJcqfQ*MkU8g70h^HL4x6kev` z<|jn%|K%D%LZrNr5H*~0mt9w*;Ry<_)$jtv)!s82dakmGY{xu9v;H?Jtu#avK^<@+ zH9SCFwrltfWr$7C@Lr03ipu5kbDWw$rYd0m$4B+VHVs!jQJ~?fC-!K#>WM-Px2pZJ zOe0Wvr4wH3gnP|w=xWtYkcM}Ydy|!m{BHplr{QWZNO8h9I^hKxepKnkg%XGV)$Vs$ z5tL~nw0lPG_mxg~trPAQ-_R4Poghcf>R%N^Itm@e&L#YJiM^fhkOa;8U-g8=NrVI^Ji`gkcf$ABxzhjCgiGxLR{r{`sc^z;oN%|q z|MrAg%dJY|3fBr09_xh9cfvEB@NG`GwNN7%rzBkFgjZ^~>bY7c+-uf2Y_3MAt zP^6OxaZY%O6TZ<2FKEC~|7yY|4FvVP+zA(*a4xA~i93vy#}97}Pi367KZ{0SKLOEj z?k9QH+Nj~?44LoIaPEN2%QW1q*eM5>+P^viCMbdmO@!FHvY|>1|6M6rtrPAwyP+pk z{h)d-_dit-Suc>fpUUH$@DwL}qZ3~6FRrZrOa3L0>#W=f7oBi!&VQHK+X)Y`IuTf$ z@B}A3!wJuK!uKfLzWxu2l}lWziJoWywC|R)9^-$opKFNQw}I9G(2OVLGJ&R8o{Pja)v|= zHz*0zXt-J7wHmG_%*}7;(Uyw7+k9(7K~qKGrHRm1;ocgqCSca^ETsTJ8oplPAu5;4 z&v7di7lo?==6`%L6&|VK0ZN7}8m?w2)(MZ(aBCCAP=ZF_t?>C8{`gh7YEm>jP|?rO za5Y1j8ty6UTe*!IL5||0d=2lQB(P1xD^|)G+N0s>j;ch%?ys%+ED+U8b^~4$<%s06*AxxsM#!gM85*wY=WDo`>9h8?O(ReZ6==Ac zkv$q-pq!Q!YIvr?OEkPDN;#$jm)gHN0;-0}G!Y6FL**L2P3f+p6V5GaSOuylyz9B# z|J0GrTrZINpE}Y7X}CJlg=l!}d}YMcaBi#oVr;C2Cv3IKf;f#Jlgd0n!_@&Q!wJuK z!uL4grB;o=@|xUj$~Anl!bJ_|1zEpV!{1f(y%smD0+k0T+`j&IR}4jJA}myRiiYPa z@6qIIctM8jxk3%koGw>QNkeYs)J9a^P+;exhCkgbmzYa#ShDCXGWT}EL;jPa{aG}E z7ZgJY8m=agq2VVK{d^5Cohg@ikA^42%e;_r*8bJ*SD2uMA;8Opq*&z#R90aWYsjb~DrJ<`;Zr1QZ_5u|?;ZAt$zq#E1=l@$E8Oqe~ z>q-LKobW;oCsfW*nTEGictwh4{r`+25H%4lE1Y|wp(lP;!4}1exRfUn5W>#A$f4VragGtNNKv_%;o{qSz^vIQ*}6KUGlXBtoSVUh9N= zr8e}0YCp)4v-(#Bk&Xff9_NIoIN=+e@Phx~Qu{0U4*_d`C(FhwyGr{SvByOn4nc-6^OP@&<4 z|C4#GhMN`6Ep6zzNQJvK;Hdw6Mc~yyfZeacy)|5ITp=1>uIPtrc;r8FMk6&m;VC$4 ze-@1(^KCgotcIs5u1nBxwF*)+T&;pk4L_|^Sw6Vb{?!psHB_L9ut`a{P{WTayi~*Q zDZE_6)eKeEbGiSuE07zP+lvkBEL_QHkcLlE^usk=eKXRc;Zg6%_Tw~s$~#u2Rci#x zln5I&{Gh_OY4{O^@6qsU3NO*{CkijKY6L;MN1A)o29Uln8Fi8oE^FW)1&I(GSt^9`DHsTQodL;R%eh_OEuoR}?{tCc6A}c)0_Y`rnsI1kpjjW7|4T&>tBFvl@Hh>>r|<*~f2{EN z8t%Sbu9_5;%i|v&HY4X;*siH85F@KOy=kgM3rm1zWZN`!I^H@zXdu0q3u6<(>~0~Ic6c(lT6Bo6

Ns^Ok{W&LsupRZIUm)Wq&yh7y{8Qkn#>3?2*WP!I`z&c<3H=}|yJY|YJIVEU# zq4EgEZMB>*%btALDw*TF9JrLCl0N6{AdpSV5zG#peG6Ot1UYbdwJ1wM9JuTonTI=Y zIcqYvMmh-8p1?#F2aa!{**~!kys@3)Em{YT@7>uy2@c%dPVw~~nOixQOMH*c{z-9& z;Ay8Em*K#T4m{I=D?eKxNjExh<@@&%&v)R>?vOx%17}}sRzG_jxJiY$ z7CP{j4!p#Hw^BK)|568mw<^H3%z?Ld;N=dyjRUW6;B6gvr2|)gY=VhJaH;*VD)4oP zP~#B6&wqaPJ?4TOc%TCh zao`;tc(?=aBypwxMLGzA93og8cxMM5>%hA>@HhwF)qy8C@NN!#zSTj{-9expOfr`$ zzx*IcGaU5QAKhSrOa~q!Y07^#I`B{jp099e|0DlWge=|W5TTbtgaQZN+kx+K;L_KF z6t9(~>L3Vrh*0Lh`#JD(2j1U-S2*wi4!qKVvmca@Kgs9@4uU}{ z$F;_R4|d?S4m{G4uaXB=_BXx1Ri1cY-*`0$E^?>nWXFdCw<#n zXBMtS29iU<{~|l^FV}HGyCF+-A1IQ;L;AG2^b~`8PE>^@Z%mCPXG|r+q9srNtY zl1{|1L2ZWA>o}(V9Ixo?8@7h8`$aE=4)^Q+)P-j`-Db&)f^Jj+aybe=&Vk?_WF8qG zQ;2X0a0lWltQ@|0*erXD>=1ZGiS(6TjU?GAM1LiP-60U!y7otbbYjbbAo-;NP*~D)2AI@=;EID^Ac@b@Y z(hKKD4&+BXH3*F??fILq5NzqeyW&2<66ix)66j|lmK-DNUWg^94t96c8HAmdQEe_g zvS-V&hDOyH8r1z`H`IM}TRs%g)B9bu6*;3uEM?OAigHhRcJLTpewxcJ;$<1CLJhxOcC<8+U{hxJ1F7$5gxbB$BZJv4fm zj3s)Za&!bguaiMA$F%VInCVR{n`;dAc&k{?rG~A$obCo?{b0n5jp?W}LP-;ijcn?HKcxE#{ zyjU+hex@V2E%=S?O}-T-jEx`*g;&R3*IhI0S`bTge_RlrAD8129!ogt^&asTT8$s7 z`_V<1Hoh(IcUWJvY`iDwFcR&?lH(F!IXgVSjjbEd04_Z?fDI4uvgG_C_TD0VIH6O= zVQpBw{9(zdVB^lTAu~_P6=O4XmL!kGe)r(a#}fjKLn?JrbTdr-RcjEsObj)>fMqHo z#+_8#0LRVE7a}M51ynRyGh1}5g8#1JRgCiob~ zDM~DzC^;RMHBb`#Cnx&)C}o(B(P`*alre8*K;#k3A)J`_Pdgq11UEwT}#3OrAcP$3UAmF~EFGiu3RRYd)5ola{QN0d8Dc6HD&O056;AhgMKS z^L$u^!h22$@NCo8l{?NB1vb+~Z&x95N{G+GU)8v9=YidS;(R_O)b9bra(c+On;4?RsudBd*Y84;xR4Gn;D>#fzq~Cum5K-TUwg6p0cVZ1-Cl{0$szczIh zOfxAThwFiv0emQ~*Kuu(>(iOOq`lBKzNhuUKdk+qWrYg(5fek6$rq%$3j!@zU;qLg z5Qxc+vCL(!p0RhtM`JxlD3T4T*xs^f1M zduFm|c7!Jx>@T`IvIC5D6l;HRi2Md)&BUJ^*#pRx^f zjq#wzR3`YsayF^}Kw3xT>PH~b-NXcb3a*w}K3xi+W6Az5ZNhQ3+O?VXz`iAdm^p69 zF%ExYjKgYTawA@V`pdI?x;=zArt|;CkUBUaCg+jO6bDk`g18&>iO6DBEuZd(5o(f$ ztFUuH3;r^u&fjK5=^Eb>dM8DhuCNg1V^fdCfX1f!DY#f{dJ9wW7{pk1AWQG8z8!AZC$w~f6wa#E8M7NPSzcJv&JZ3y z59yIL`12`p0X>^(RAX1J>gT6SC!(&2D<}4=6tZW>dfVLCyz z_1o+=d^WC)=lENPp&_F!6o}`)mkg|^Ghjb@2Mxa?%tfH#i)Jizt1(nX>~7C=O(}?S zY$g&HmqJf!_tEmu-3Xl%6``g(7J+JB8rdU$MJBm4=9nskY^Gk2!7&q6&wLLG&z!~u zp7{iqYImvgAZuQ?P*-^ouL6pvZtA#dH*pN>hB+rom=8AS2SB3McaO$WeY@{P0<3>r zy@CGWGxu5d+=wWavE0C=u2@vgJ>fGIb(2-=l1@%a%Q|V1wyFX?YSaj0=e#!LV`166 z9wbfpU|w(j?Y|5{Wrx`Ab-d!F9jiMl|5+!!}BLYZ<-L?^j#iXnGwcRpo3iFKkz zP)NU7{erX*ZP>r=yDI%_8+4Wa^(~lSSg^@B3IWwQgHUvIhSnpIE@m9dv?0@n%wV(5 z3=C6xf(7M;1^&JL|CY+QO&n1nwTVu+7ym~4km_3T`FWH;HG9k;`~0kn?DGfL;PWBR zwc*b_QWmbo2xLB&%740#&;oCrzhHVk411%|&j+>0d7$IY@Z6Z}pVED+u`2N>$AV+S z^Bwtlm}Lu}_p^@BN$psid=+lBFT;mS88Uf-WzD?`lsKBLhgX$}E?=T!=3)o&Df0t9 znU;QK#_U}PS#oET$KOT)slCZ#X~jQOf8Y2tXf;zi_v+j&5Ga%`yE7^X$3^lXW3zaTqaxk!0J?# z=?$!zqH~^cgN)TD+h2qfo>+PFftyumv_FtowAs z-(1deqS9>1D$_;hj8HAhG1Je=(Ue$hL8+K*B$eQ6PIl?d%k=k`bghKig4&75|Ng2JX-LNZ^RmvkW zc0ifvc^u1NX2cA{<r>ch&Bj=IMjr+}G6QkBlQ9kk zs$PUtxwqtEh|L`lWXX-h5+v;UK0SAYJ-$#A*2uqL@+Ly|stlLh?okf~vO0>d``sW! zuYMLFrAByvb!cEj4RW6~fJgnw4|=6`x% z5PDfd5q19qVZJqrp9fHAofV;b023ITr49RZHiOy%@1wy)=bWuy3t{Q?Eo)S4&bWjC zR!8EUQnZP&nR8>}B>!cI55GI^FK@0V7u4Sr1&emr5*bU^E6xFtl!2Pu;Eun zUd+$2h$CK|1k=pjO_{r8m(8>VhDq`34?G+yqzy!DA=L#b3x>79I?H6C&)W9<=l2Z4 zw6)!JtM$T5YbTOA;r80@&C16SZcJWUKx8zw(99vn1;4DZ{O)RlkdoE1(PW6RV7z@= zcqJ=1;No~F=loLrtKwX#ZiZIN$&EjXmYH{2xRd46@-~ikqH`WFMRqEYe!TjOIPJ91 zd|gL0h8w>M5$neD*}ocu*VbA1{B$eIS3y{<7aH>l<*%tCHNtZb-3HBbDE)j}jUi7kAFOd2v#TKu4Mylz!s3>!HuTu)}Rgxq+I=v@Ko>hfkCYx$4C)V#;Sc?KmtxZaoY{E zBD;-~Z#|Do-zjXBEbXHxX^bxRrR`2(V-LOA`*aw<%i3+tv z=iDFDxo&t)O;#n3RoxHE^+MiDo%j-5i(lIAk{fp7M`2R#B>pzqt$9P+-hbOn`eF5!uAVe5yaNLWT^VqITB z`+5yRPs@IkCNDT^Q7->&N&IWLW^WtE55o1vwywMvuCA~9^Y^bAgwC(G)x+*@eXFdW zH(fRezi)3Y?0B<-uKF89YEkqJf_$5DgYb06Fn%`V!`|-f?{$UMEQaQ@yV<6uTbjR!7-^oC+|L8p+SO+I=4*ox zx$|PvMa&ZDHuM#n$^QbH@H=aCpLqzo-r3f4$VFM0FA4wn%1{)ui|TZrMikwBZxG?z zoihj>cL(v0$_z#0cIOe#9p|v9F{4&&rU_>a!o58gbU*YHKL22%Zc{&@*@rW9Gx`WG zd`NWxwMC6TYDf6irwl^y-cbJTNrNzJ?;K0?jj-*weJg&+6P7TZgadKMe4*`#N- znQ}@EMKAAl4LQi{o)9T1`>cl0xZ@bdnaLQ2tC z-CKVNCyH|1dmdv6;=rH^vdJHZ@>_6y>Ej;mCyy$EkpFT#nSVJ- zFFafNobK75h0~?WbTg+4ktddsAB7_)2J-iZ>4hgJ#<=%EW0qRtZ~NfMFMe_#aX!OgqTy?b&q~15>MSHyyqajaN|sdd)JQ?&;76mYt6Hl zc@wTZ%R2I>c4Ou&>!PE#gbig&-K`%edVRnfoeSct-^UzqZj|oUZ6WjA>=q&KF+W;a zYr$FoKJ)r-WxZusdi|dLDU+CVxCJes#8b9o9gYfp%&iprF z`q#<>`3E};^k4w#DoiME+w%P#h>LSZsr!0K-B;LQ5Z0C7ZIaYW&pkBG(BmqkU3#{O zt*3mCt59(%)jhO8sRi*ZgD~ZCe?Ax2&6oSQA9`C6EC9HExjWw)SHqPJ{DwCSLjDzh zeh#jOu1t#Yc!L#hRjsr>TLlOFvmGmi%X9OiZD*pfwqji-GVL9yY|T4&jSkB z$pKprqK}^14u4-w=iNi~!k1S^>drqET3lP~{`Z@TV-7<8^0iKU{ObmxA0NU)^R9Mt^fbck(NtZABKpbSri;6=D1!TyIqP@cy{g zR)p~Pwitx2H~jhYxQ@9oxcNqWN$MCV>|E}$R3Jp=(Kne&#jv=qOzIYW*Yq(RwOs0 z-3J3nj(7x}=v({R?#K5vjq6JBWXJf4ewly>nNoz{R}Do?Z?_=sQ=lNl@XR*|p_ND7 zUq*hUI*EG4ApBj~kFR>!AoRIoA%24O&II=l^A-I>;9Gar@}K7!grpy?xQ}>65j@?5 zPX1$7V?Wl~yi8v0^uom-SCH{Vqkn2k+*{@;YG1!(5SH9M?H;vB0srJ+BKx^O=c_Ne z`?HVEb43nv%g#S+rjQMWB4d@65KrNiUkk|$A+q{7dF!=%AL)KC5%%5togc9l75v*W z{_jkK;CufNe+~DS?>}zy9lmv5wbDx}{qD7}$9~etW}2R9DEje16T*K2{oiZ0>aKk% zBKeyT-EU#%Vh`(DJPhX9E<@qkMVx)XHmT!yeriW)-JuP}pd@oUW_K$Xa7pSlL zV;1(qm49^BO(+(c{5g&fS!odB|9sYPbp@(;fROO#00YeIS!pP;{W+WHsy-3sJc_`g zTU=K3{-bV0xBReh_3<>9T>Z2Rp;zrd-Zuk&sg2-ozGx^qRQm_f?LJhr`|oAMbNW)` zze37?(=^PD|0M7&(+$F_|GeTma6b+Wv(7yE%mQ~+efJ0lg6!QoY*7suNh6+G$r$12 z)93g(OEA&Y^+xL5mI$-zV%*;th$$o&PwvFwlZ7L7!^mi%uC9&iEMW2Wq#}QtH{ln( zVA#^1Ol=nT1KU!q3kbrw0T$BZh8woLPlo8;+qk8QbT#gYXYSe@P>OWLFGtZ1giO`v z`fgcdplb;kV(qusfF+vpToD77F`LIrY{+3*GL}9cZE!&|kN6T{OjW*2a#nu?cNjC- z;l*c6>CrHpo7?oe8TNP!f73@oYaIgY6MAlg2McFC(WUp09xGsfoeCg5T`)=;2kZ#h z6NdfB)Hog4(j|By>xOI_f>8`ZIR+#2FK>p}zd;z=Lth36gg*_a-N z>`8GxhNP+!?i>cV5V_Avy=yb%tRHVg{lVjJ29#l_mIrP2&z9IssfvR1HD_7Cey`tV znySX+IXrYXt~7^mzmE(p3$i*W5_3t~I6lMx>ADkfE$?ncCnY z2F4UeHzF>CMABy(lO#hV42=I@efdh85IyyG#~)i`VkU#Bxe1w$%c>^iS;HVG-+K6O z<(6a+?c+|?TcN;8EX~-gHDFm7HH$rsy^FJBrFrz0!2PPQm!+opUa+344n`YY%L0K2 zSXclLY9sovKyw7fAYjS)5|4oLA{MeR>vEP{_TEIUdw?Y;CLqO<8x!D02Y8V7~#T|NY0p@&-xV} z-EB=|J93@$0P-b-|Kq70pMZ!s+ec@#9|z1hDc(!8*>d$~r1&nzb@$TIT)lBx=CF_N z2cdD@FOXRBtP$OCC$^e`B3);?9&t8XZ^DM1O5~{OPsW}=x~|liorLaoMqh`7Nfi*H zo9b9eamF*Z7YwY!7--4)8o0O@x(byXXcAaB7h(ArIRGKCZz$9!LEQ@FwvvsrVh3hp z2(yuA@@KAV#y|+badxtgSB0wHlTGe~$?Abnn~wnY5~A1>ng%)QLdMYH*(0tPwwc0J zJj)dB!VDsh%YDPMR z_JH7PJnfXT;f6s?e1ox1!6Z*q?UmdyJRlOKDGN2w9U`-6TcdQ z&{TvldvN^>^msE8YWzMN`M@w#%G@$IgxZ>smK}nji1TCSozMFrFK1bCajd|=1O_^W z((vZQmju(v%}F5XOIJ20{?=vFSee!Zuo0Ct8F^@n=-&!GF3)3h4=il*^e(L6n5dZW zSTk1p{aL*t8^94WaTU)oKXqatH;uj2Vk!tho4EyD*#|)oRl7;;hrNCFZFi{G>N#(@ zNm+94S2vawy`d<6-ktVrK`f*@UD1O0wq(kwa3aip8f<{Y&_`lq54yhv>CC?sY@pw^ zAbxY11DZ=p5mnuhqjy>D=wuMo7eHX(cQgg529B9oIgWP&yUChIdOP%$D@=+)!WFl~ zT}*ZYguTI4ZA1-3BdwVx(gr?UW+DL--|hpm$hWO(K2ysxT^J+nc~}W|vHXmaa6~b% z_yu!WBufA-hC7zYlJ{gubd!~yW5zss(%)g()yQsM3!y$ONgvXcPH0KGHQf@2QPqB& zvLVhu^IMYemN3gIPO3n)QIyZ1w_1|UqziRxMZ$0y)Qa>O(*=o9v>DXdd%a;lh&40z zFLsH3{wVxPgzSZnVam@j!g6cLc{3n|xe}dIv zSE=dvqblr8rz`-ja>{-bFIYbw zqd%5~7!AVPLQC8?pk7+F^lvt@>W7Rn(3Y)9Xg^;RQ(ZTRBFo$-%&B=1LICrX>Af&K zwq$Q?i_^M7$j;%=>&|vI(9G7Pr40>i(Uj=ZzCDzKzjVSo7H23={S^F5@mHPOR(fqzx1AWeq^umC!!;iGarNocC z>mG6fiWgX>4PEGbf2>10)9?LBYft~Ns39b4wwYRtHBjD6tR#qLnaKh^=otfjU?wej zBLZ&ih+pfu$B|pM`n!wKu84&GR`n4EHnB$#9o&v|<3AWe`cbli1JgSFvdr zFDZ=4{>`|K{R2bN3jaGM!MU?t(o?d6BgPX*+u`>2godKRS@8{@*K|o1M*wBXI=H8X()p zh)0-lHZzD`fhcAZ_Q$~f5ccPv0JJUx|8kJ$d}eaU6njK9I0X+JW83zDM^bWb4Z!Vg8@S|Ax>sIx#% zI#l6*v>0gbj-i*Jy}WKl zkTVA9ldrqr9X-589+Q_AV8&CvPlhAu+`!~v23ppYbhmy8Uwq1WM{>qpCyZI_*RMit z$5{QcLxicrSXpf8U2LXSEEwJ>-5*od@_Bmh7t-UhyyH*}w5~UB z9XngqKtH!^=6j~~c zaME`Wm@W%=NddGBvjr9D#@@xp){BwM8AuanRXBhxMY+%=nxD}hMu>>9Mofh{ z`klBryDnf4%7Hu}lX};tOu(GNn&$B)kc3{gnKGF<_Em%9n2Whkyd}K2VFK~?1SYZs ztl|UwOC?Al@?R;u@6{j$$sSVhXZCV@Ygi?!T}5)5XllkHoQ%m$31T_(nr-~VC9oES zMa>M#swHV7r8h_MI1XQT5L=m`o!2?S{aHP(9+%|3*HmdOipSc=Mj-!UD!O>peKytH zpcjLQw>1D^c+)4aM)jtMKqyYrBlMHenQJ~}F9fVdbHMunY5r%{1(d)JvE<1C#ba={ zxE@=$=;MgYKIk8-Q7+7{4#y7NP()+)Rm8{8bsHvQvaPko>`DOCRCDHltOz46T-v0V zeqo+WeI5H(pP_zGQit{r&}IW$rIaOIdIy})Tt&EkV6%^Fa|Xiz`_h%o^csTIwK%)n z2URv4#N>qSN6-q>Q*e#RhUrqpv|L*G>}C0Xn{EPo7~a>MVuKtzeZd_x)SP#2$J zOZ{BE4Gv&-*O}oEv0q;_(oZ~sp@33$!G%lf6=Ure))_(Lx?f?3ov<{AZj~R4&5Wlh;L_i^`5oB6nEFMngY~m%P&ImSkh<8ki$Bs#DCaZLir7ys4 zR<5_R!)ceE#Ls6kzAA`rFD}MErc*tFZN^w7qf>Z<7-+kmq?5Hd(?GMs+Yx6)16rDR z5V|OE!7LnGZfVJ~CASDf1UFsA4wUVEWJ7oySB=r8fyOqChL3oG?Nr!--9EN`tzokf zzSVQKN=HUY3o_Q)joA;S1kfF-O=w;+V+RHHCYc*9o#WgTN^?+sCk4BHqduM zNzXA~{-Ycr|2+U}x}&(0-dnQD+XWm){{YTTZ(dVkULIsXC$YH)mcfm)&$tAZdK!A(RHVsH2D(W58~6TLs)v!j{8R)Y!pJi` zF-h-WHwi2DWYJfZi<4<_7zxJV@y}tTqt4ucdiEi`{J+CV4zuc0Jr-7K#3c%oJJ z#Ctc&@lTyNhsK4I5M7Hf`cgOva^H@0rGw*feXz6&$1$wvN?Z0L{(Nzmfrj^kPu{0f z`jM%mnjY#$x)OhSs~>5_KkjXywYb;aFwnsMWN`a91Ka4KF<7!zmEu_h+*f8ZJtv(O z-WHdm_tEwJ$u~X^u;G@n{yr0-#3p;zhSOyOh@a6c^JW^rO|Bi7i(SJ@K+Dfu!vdAu8aSK4CV7XRX*V*d(h!=>(kt4H=PTjUx`I!Qf0VtA;&`29g-3u$r!$M$oL$) z6UcVL+pf9Lm`Nmwe;t8ClZb`aJ>R4wMOQqkj?=wVAXsC%QKYa?2M`h_hC9O z>Ezp` ziam{u%D3d@;SmY?>6mS}Ex@9TVT(pM8nr0?@TOL;;j)I9A$o(hqtoV$8@KM{HIyiLus$W{J}GcNS; zEHbm{kqfK_Jot+)7>7K3P|CSUq)XGCUrP8PF2D!Aa-lnuNI>%qZ?XpQK>vz#ovWvB zy3mRw@&-a+mJe^Gv+CTmQmHiD{T&8~y-{U+R;CMS!;4$_`jQ^fm=a4_U z9=xNJ@48rbOHzCrBqj$hBcBmJ|BjJ}bPzH2Hr+9ooNoImb7$5mFX=^Zd+*QFcfO@( z-)eUcYjq12*~GN|2Hi7{tmM56hT=~1NgtP)W4~pI-4b8KgFR#^PPv^g-zG}8(zi(` z%jCfgmX!xA%EvPKOCmP$T7_icXWXJ^GX>!q{cIs=*XYGk<}=gY7R7fL;$dp=f=k+d zaT+TI$F6U>uJ()3my0_jlL+Fu+vdUzSyL+yFrU!3Um)IeeF_GcMKs|B9EUEgbD^7G zAWxbM{#x=z5Wc!Xx22N6&LjUujvU|2>jQw-(ZjK>4~WT4ii~1!ymmMLO@B@$`$AuM zB1vN{xv6n%jnX<1JuGX5g-dINTlm?#{&Au$aM%+)J(WiK;|&IvCsdbC_VW{K^|UCR zgtWd9&kk1buDBQ0F80^5n?U?eI{H+>V?CX>l=$&h1U4=uzNYxc%y+l($~pp=LB+Y} z>TLALQj$hi(;hEkXrB49OL6pzWGT^o-IbomAd|@!>b(pn4a=t%Ph3Wx=*UI-%u3R? z#V>y{Q}{;hrhrT|E}LoVLp^r_HEhv2r54zZy?}-Dy)R>FIj{V-?#U@Q`=`IN++$Uf@<3mF+)CmJ|MNXPZMTNB(gkp|{~Gc#`H7xeL(I)jo~^@4>uGi- z#g^=1lC6&Zvxcdw%@ zwK(+rk)B_Rb>1=hfa&a_jk8FbP8-kE*{ZVeE>leI!hpD{PchVoN~YdETBk0V9*M8f z(OIOcbuO6n9Xz(f^b%d!as2aQ`KdZ(-J@pn*i(@4Vlfj~*op)KoTA}9942Tl?qGr* z)h(sfk~E3;{#B}4aro!xB`gAbDE=}PN5fZGyhVs$$)SH`krreEZM=>Ij}4H}NxZrC zbz0Lgc`u?)Y@&56>L}-N^{;Xzq$Noeu#*k%Sdbt5tj;FhJ1M20*5Vk%!0Y+f>4tS! zi(ZVS2iB36K2xA+$;I0rQries;tyf*R~Fw{M|=oYfpys=ugQ?*Y=E1tk6!LVx2`82 z5MLU(0Y_Rx>GK=NVseFkyMe528G8cu&^1n4&bkEPWf^4WXK?^svXS%%NV<#M$v?bM zb)c5jH~Uo#ydnn9I@q*gH1g9M$wVU1HaV!d3>ub0g2-4pGl!IrKD5%T{j$YK^_MNiF2h3PB{HPfE}Tl@{Vw+tQQ4&#gC827Ju%l9D#fqga)Fl@kA%Tv`#WUMqi&JxnCn0U=+D)WSlNM=mf<9?dg7o$#(un^PajGHh zHQ{H6#KP6Y4&#JL{aKA1B%C@^O{{C03!Rup29mGnt9e*s7to`5=*G)v@0ZDIx~;F% zvX{v*(y@5MD`X@gx9G)uQkbys2t0@L79(?$7uqIviFh@``wX^sJVxt0Nsg8(DT%93 zvzkX&c_jXb`luSjCRJ4*XA-6v4fXfa+piLf_s#G0Y(FN|$t8qYVt4kTPLc)UKWzVx zSoGtIB`>l;OpG1I&ZZtU9MQ56NvUA_FKZ+#hOErc9W&pWj(Uyw`SymjDx8_1ec&~d z+<1I%W1g2h{x=T`-2PuAqB%lJ5N23O%jZNqoEZs8Gvh|01vIs}>M3Uj=-~R;Q8N?u2cG@OzW7 zKzf}N65YA{V$&OB4$;keg|2)Pi{$3T^vgF%tZwH4>iZVmbdy4nJg*C43?p}K1ZQ|F+1lLI2j#dg}rf&a7G;%ZX*M0pn zP25Zd>GFQ2J2#VoGn4V9E!IR_SrtA!fOa&LeV4-v?Z}O_qp^}42icO6m{20OG(|%P zjqVLKcE~=Ip5uQ^2W%l3x_%$h!&}I1UFJ+Wb1ONlyRk>Uk2KO_lq?Eshi^(Ed8M7$ z0vmm$I(BB&mP_n;o7@6_$ImD*uaX^gwtQ-Shm6vFrKbzu!9%XA7xeUvckmGLV+1~X z2d{L*LG;Z#B$m%Zpvx}O#=T66j$Kpnc|DEYg~wWbAX>AF)ObDrCY;620;QKI#OZX+ zyBOrW-Y3tKrgZGPqFebSCr?jg_X#{ENM-zDw5?r(3PbDQpeAM;Sb zyJVp*|9_H7)9wvb{I=7`_lTL6zfYFyzW7_xX&(Q212eI>rTHI_mxwHHQLwFn{8ilM z)7bYgWIT}!wEB}aP`Ha*w%epV_K@dvMYWPri`a%rLvWi9g|L?!7B8fprGX zoN&xAFaU>6Cy*|iHf|umrot)#lT`rfRN9d{d})iu>?LhH4X2TJ_Wa&v`s@omP1}p3 zpvx!pG-4l?Q6&gW*@uO2KLoDhEAz8nc?}6-{fl2Dw`cgv&B*X*bi~k?rQCL4LMgZH zP{Qg^Y$GBWVqcfUw%(HSg}9AH!3#POb$L=0_79H8QSQ@=`-y301}d60bVv|eS zQj+6JDQl0(-N5ZtlyVp%VgD7MHgz)_kxPE|icVD1-(F|fNBpvy0j_GN5AsIG2F(2z8H>s|E7AN8+ z)K;yR4sKXC9|j=(8iP_R>W>IbI4b8e=@phm`rr^r)~()FoKQsi>PT|&w!@fTNlfvb zPl$oIWaHN(X>~D%Z(T1MQ$kX7u{Y_l5;9h2eSzYI*bj9bUZbCVN-}k8F4Bl27}0hf zrEeWUg=HSr)8Zp!f=g~h&|&KN8QG*8nor;SjP&Mbf2^lhJ|o9HzkLP1$TR(ji+KNa zTJSj;$j24w>Fv*n58n@gy3a|LZpGI$>nM5N^vn^qB-|TNA(a@%zhU^*D*D1P(uVpT zBkhpTp9hPF9wVy=c}h!aH4mD#JeuWYD57x2yRP>}`r%2^)zx()RsFm>_yZKJ2VZKe$$ z>S^I=GTc?nhMiCUVJWw!EzXd3uDcoe{;5oUIZZrVmoqY2(rHPpXNZq(NH%@z4DsvR z4idTWPaeW{Uc|@qT)3(=k`p5)r@L^~8G!LDkZgDB^Z@$s3>iAG3@6ffsWpK)kNrZy zGz%Oyzp4;*fJk?-!eg(zvd3D(a~1{!#N@0D2$Fre;}x26mQ3^9xlU?SAL1e&ewp4l zOZMp|XVHyiWTy8syHR@lrWo4}$-krQ6z6H!KBw^eUG!J)i|KJ zw^lOv7cL@~M_)cix;JmfRIyJ%@z}8N4pixdb0jA$dkq9#n1EFQ1~XWI|JnTb97NU2 zB+gDY?R@+iy6HR#GR8{jqy@w?>@8xnf7kc) z+>p8vAxuB(7#;8>8PxmaUiK&eBgvt6r9rpa2b(oE_)diZ{Gf;ub+aVJ58pi!+r32h zeM$QI)>@Hs7q$RZ8;?DQH?5R>McRgW;l%+4r5x^B$EsOcyKX~suliUmw6|m7@~m{+ zSERLWiIpz=iu7ys$}a3lbC`y_2P;K+#2?zy&%YvOK5iHK{#SUzYhDptHBi}gC5Un7 zv7+s6zl~YjW--#bX!nJ3?5dWdxDb>Nib3-1+j@#HLdO4*d$vb#Wb zOYssm+Giqhj;4H#ZQuoZ`)g98J9>>?xkuPbsLr}IhzAArR(s3aQ0?@uJ5aF>FLsPa?tlC-gS^N9DNKL z?32lcnQ->=h|kjDmq@_WH<=2mVeevl-9(B#PRMmb0maKp?UDp>3tKv)yP3rSyJVfz z`iN$+qXK6F(l0KN$?g*|)k__v2{ILMnMCj(y{V_OFOw1OUtpG(HsZ@bKDkU{x^ABZ zM|vo;=Y8?ZMQrwDMd}?O9>a|^(MorPwEGp(+U5E}q%-OY@rUnT->#>Nui!z?7zB=7 zA!cFuS`R+DmkT{|mHf!}eO*rru3-RAPNm1MkzvNm+vGX;hv!g8-&ET4ItjtEoT1lA zq~~*ty(d){p7hf4E5sWqblIk-zg@ve$s5;+pGR)@Xo``n18ZBw^vrb}W`DO;PybKY zo506>g#Y9D%`C03xu44c1XFj`;_WS+*{$6c%KF>UJKl98p&ph)?-BU_6{|(rRz;~kS zHjUce;mGXuI5F^)5`$a@EYyGb{nUmv>*3MCqV67o@ckcm4<(V`>r*h2+nKEwolYx* z4ZBcj442!Kil`l@mBYB6VLhWH*WdgxBIGLb$)^}1+(N+4Gp2-@j!NlYy4k9DoJjaA z(2L?{mHMd5A7AQ43k3NR1V)~P%rgRkWoMOI{zll;l7~j46q=x!JfOyjGiR0H?$HDXkjnLApJpFlB&R+5`LxK+)-(Qlt84SRH#V z!n!Xf+9qPl(Jz3k&PIRI4pabns*{+1PN~_u2KXrAOCTO6j^|S9P0mfQzQXa~*V&%# z>Gmb<&hrzj7w9A{uuveQ8UQs$02 zC+C&n70Qp%I!D|3X=0_iP&_-Y^p9CK`hSV5CV4|_iEXrWSUL7{A>@M6^sxsSdrXL? zvX^HFaY2bM_uy~0`(Jv+zs0=^;LlIz>P6X$O63wOfB+R$glKY6i3kmbjFY4}hJfl+ zyWRdJWI8Y)b>%=1;6-7%s023L_brAXBQFF*F$bgmz37UhKc*og#k#h~_1V6z)L7(eNn_45SauyR6K;2>qDcmV{LxkreZ|FR6 z^g4F z%|aZO3T(py60PGf>ZT!tuBqqpR3V1mR1#@!&xF8zQ)y_aHKO2bH}h(B5EoQ|l_@&}4Ir&3SpBgQ+G zmZa!tb&N2F~(g!EF>vZC``^rroh4ac^ z9w;wrU3!cx|% z%Eam&C!%ny$nTpAnPmwz4doLs9zZo+*qm(k&RKif`lJR;``5$Fy*?*r8>#aDH{Rh?> zj}d?8ADmIN7Jjdw^0WOUVqYnL@&g~^oZ+<+toV!Q*NP?B7FG#N(`6*xMv?-N)~!y{ z*gHwLC&j7P%DcvU(kAATx-|xEc$gqszfr1})(iqpc7{Y6lPLapql|!AMKiZDq=tg} zqyOPMYb^2deM#28iI-Q9tedh;j(H=L>A0~td@S@?ZY8MxtVC)ub}e9~9=+xM&V{3} zqdNvN7{ax7lHtk@WnKB6(fTbD*{@2Oktk(%b8HISrjXHkM_a~fDZIldy%@pSP<~;g z-f^6>&lTSJBfS`?XCLyLBlM1gdUhPj?~jla3p0{#9j15uP@K(S@QpIzL(#G%Q}s6e z%prOaUW!HVJ_z(E#isL39hpr7E zvBqN58q@(v+f6aJ&Z}L?covD62q_McM1YG_gi0EepK43gtu2At5ag=q zEU1g_w41(&M)qC}mCjrCN8z&U4=7S9eBMWlrk=`3+eVI-idw*Ay@#@-qrT4&B9gJy zLEZNIvu0&hd{EeS=hk|uV$q8V5TBcBx3jijI^@99OU3hZmXu(w|PP=TGY{1hQ8 znA)^R1y$rLHBz0!WChz%q^w{YG)HQr`Vt6I1tyu)NNu4c)Ss2LB&7?JltL0?DZ06V z8xCo(sG(LJ)eLKL-4#qtddZGK96&g>q6MqD-B;F0&A}Em6 z<=xSO#6T9r8zV3(kOlHnJ#oMp$U29YK~A9j9?}*80#+v&Z$WpMK>N>*J*gCIexiF| z2Td96Kr(1<14V~QY*5)>;5-7_uEK`x6Wc4X4-Hdg zqAkXr8kp!y0$^jMDah`rN2<%w8KB{kM3)0}5L9PC=ySd3AH-q}FS}D_sNN=&xITy_ z1pa*uwK_i3IFV{*dWJ7DC~;ro!mlcuU+JSz$>3-o3XYN4MUH{Gpc=YULl0N%rp6Kf#5puhmVCQPo(!jt}evyqdr}n()8liBUCK zHt%zm3tcU?g|9rr#m-u6TlqC-w2|1T{RVA2!yPlj*>K$IKgAu7B3M6#o#vuj9rm!~ zdG53S#aI(N$sI{`S%N}=MfDgCzyCsKHDIUN3GTSvfUTt%u`rUk_>TsiBeM}p;p{jU zFQZsbez&>a(XA<4%uJ84_HH$l$U10Tu-BS&0yZ9N^g4$U&AKVv*+egTwP1;SaTC2` zbqjWi@wJN1VQJ0&)Ug9x^k~nj@mssOnB1O4@;n57YR_6$&4yOTSXMD_E8+QEUz@^03Zlt zrPH2r$0##fp(}ThV7g*ixz>18SO42X?x>o?W)!!CzlKGH^`tuB-fN<{Gx*$9o_J&z z4bc200PUbJN`yL~CBcXp98mq9Nc;rCKSNVVH8l0(%f4R5N<_i9hVv}}WFj98aO^pPwEr-B@&4LnbY5 z{G;alP5c=aH+|tZ8WC?48DWX?_eRu_5vC#dra@|TOV*^c{Dj%Y0rmac1S#Ez63Edr z!!Rpe1KxZ>K-lG+B%qI$Hd10jpL1Bfr)7Q$Xq5RSd`hL1`0fKXnXfMkV~oD60{fAR z=)NqSet+%Dp0l-FZ0W~BeBXhI9*jrS2I68r*4THX=ku|s)SrE9`bvJv#pUKT*}CBS zIVm5j(fT!P@zm3*Y)FDk=B;y{R>N2KWkXbdnUU!)&!=AdT<`gO zDswZ<^nBjZJ_mR{Pivpi_d%CL4+pjHa-QfN+NX=m0ulS8_W6_NbBXr3MSh~+FRHb* znyr+OOR7sE=ts%iWTQuDklAk`?`n|KmbajIE#IjUazt&aeID_A*3uG8ev5C?5DrKP zY{-k^=c~`I$bLTk7XOBXm@axUJc-YtMn|iG><^{x)?hR>`kfG5|FQKCPqa;f3Zr5v zT1ZaA;1=#E`$7wNzySIA;3pz#FsoLkLm85wK;CZCKc%458qC63<6tpoFbk@uAf+as z5rR7Y!fQ- z*Qyh{6MAt>9XpBRN~h>Pgtck0(pRp19-CJf>dps1<|WSsHP3DK7dAX91P=ak4m0NBN*#m0rq` zW|it2rIFz>$5_Md!uVk*qcBD!6z$lFeyxUytoBMY)p$$fk8AF>dm? ziauF#Tg#5Fahq+iAw^oTU9S_nMlp+_IAtwssy`b4y zJ?^bw)>(0IG^-LY`A<)UFx&&YBjxORR=gg~DjS|G@a9natf;$|RT6E+ux7^Jj(HN% zrt}bu#>TKZrE&n140gd8v11GiH}v&lsRPc4djv_M;w4wEdq#wgWwn}n6Tv_QN{z1nZPEDLE}>ZsOH{Yay( z^}8_>_VwUpQL`D&ogPS4JMLz^pnyGUa)_tb)pn;vnQ^RjQ1zpr27Bq3SHXJi`hQ?1 zgjXPPceSQ|+%JZYWB2`w0YwfKIxU2zqx0HHF%qsGD-HgF5=Sk-COz|Df-(L9IbKIY zY$wJ2A6Z)m8_#}Z#<|E_TdK({_KMhR8) zTJiBObdJ8MY`>0MA=QL^3Sp)n0`Gl_xT_FF7JbTKw|++)`IH43dYr@jNvDceDiBXT zWh%3Caq%-&!C-mnX@T1L_k~kfBSY+d0BDM+e!q)0Qy89VddkJPDXc=nQ&RQ6bO!p?z7l?#( z)`;KC6&u05Y#SAt&U#hG1jcI}Gr z(gz*_h#Kt87&8yfo8@JSzRp&AM7fzLwzbP!tYMF6Ka)k&@CC%#6df7!i{j0P==E3J zMAj;}J6Ft|$(l9YaN7%+lB@9$xU6tHx1fXnleSx7+HSex)l3#`XkVDNbgqb*#VS_+ z-ih33uj@MJEtc5-5r?;sKX;4IX0bYT=5sIcE!hp7P|^873HDK0lA_agi(^P&m`4yf zQ9JAwC9JGYbRBPfNGoSRE-?-TS3;ZP=6_0jJT{r(NfGxZ^hItPK0#XQbHcp3ON_Fz zx&zmE>jWTrHM~$I+}HWlE~w)(-c*_p7?W{eV4O7-hWBY3Noa6iKrz;Q*E-}ntVjmx zP$WU&*`A9lrDJY!@xsdPG1FGzoXvjY8Q8%)Y;3OKz(h}F)K|ZXZlAMy$rpbCgoyq> z)z|{7R%q3YnfEBp9(9ZGs0*kWix4RrY|J{YfuN8hrKsgsapZHB!nSV~@pe`(@DWmB zm8T8butVU#Htf}qK5vJx*;%lu<3VD-&(zyHq~QA-KGl9=x1Bxr|L*6v_0rgV#&(U} z^AySMn*iZo?7q%+$?jp5#D4U>b%3~izB*G>n8(8SryIFwGmizZ8K)h+=dr;`v9I=_ ztPdP}zFp(QWmkH#XkiLRYz|SR~E4*hG!$Z^{ux-RQrm> z87_Sfh~)ei){Bq7!a6j)5NF$ZvG6N)1=Qg9WHDRLs*c)@w!43j)$Rq!3Y*~=fHa+$ zLo{8=YFE3ngN8aj7gtSA{ON>bOnSV=Ot$DyFSh5-rL z9_74>_7J)CbyoaAG+WLZgw9w6>#E$odDe#+SE}IlNN!{<>4J_7)O10o268cLIorc) zLy3{Nf>q+--*7Qv1#7`~t>EIj6)c`79_8ZR3XDYHJua$#14YMnsN^Sp!`kqSBi!Nm zhD9pOf0?-bEwivMmx_@qk$V0gT-;g7>I7OZX;=0Ss=-UaHfEDP+g`e}7Tq-XEUfBC zhHOJ{8>Xx+ew#L9>`^Taa}l!&bqYkF-zpYrIRA}TOenWZe7=fZGb{zK2FcRXSD}v2 zR=48xt?UMdS+MuKR#p_K59 zih6IUV*m`#6#ug%?|LSRHcuT(g!mC+S+jTLJRJ^%f6deWOB@i(S}Qzi0Sa6P>c6pA zj9AAU{M|3PsJ@;>vj<;^e(PDgQnZZ9maP6t{IDJ^nKz${6YE*qD$y|RlPy_*vc23s z7_Eo|hHOQNuSACpY>lC6cW*0tED|p_u)5WwAunp&yb26NL84R4Hg1Nji&rbI!`pe} z7hEK4WDVE}AwJ!Rd!O#Pn0q%CiV>Swc<~K$@UeBFShR_aES^CzaSKJspILZ|I{5H* zg}DevXD|u)dI10GZe;)AzvQa%o?%e1>((Swy$Ex&a&e_17_wyvoRh!&U`iX zOL68GcA00+hE8z{#Ez9VWJEH*I&!|awuSX6lLUaKslBhV`66*E+sxyE&KxX}y@4UE zgLN@pwE~MKCh_eR^Tc`w3k=^$K)GUm28&1Qo{dW8L1R{Xpm}<>KOSI7wQ_Oafzhoo zPt@MV>Kd+kw?XQixnj^Z)~nP6WFyDhHdo|rV~q_JIsziwpEy^r?aWd99|*nboH-(Q zJF5{se9jx3df&sW%WO-6!%nih^X&Qz3Ergb=Lo|NR<~G_rC@uPM4KI~ArFPn_wf!^ zk@Z;bn7xB7Rt%HBrnz>>Y<;MXb~N0{TJll}aMA}5HUhQ8#NF(pvQ-v9aG(l$5Pxz! z+zlmZ$*;bose4%Uo#Dvdi&LeN>jeQ0s8!R%gZ(VPvJ>BA&HHMKoWg zIr^~K_|9QW?*%g55%mN`*!4^2dIS}e2aP(dHXWzSn6D{D8wPJoL&QLP^bh0>u%+Xl zqeQ#j20XZ$$Zm-4(Y8~IEi!}8U~22lfZF_cngmZFFpZ?Ah37T!>p5@1o{H>soIAi~ zbAB?Fi{XdB+#BrWjdoonJnGVd;7^6d11619K!0jb? zMG2!jDLxSwtBjfBi^OvRzaznYihx}o6SmBa{CRl`ISgTZ^kG(uUs=f= z;xPM*u>lLkm}9INANVU5YmTvJmYivzh{-9h-9Ia{vL~a9(0@%gY5kWj`|lbs%yt>4 zE#>b|(E1;6ZLZ6A{u0rH8&hRW%ydr-CJ4HUHk%8zm<^PdM2FEcrLauZBJvTTVbh(> zGwLu6oGihl)hz%Cb^|c-xU(l}sTP|ki@Fa4S8$e)0NdMK&^0wG5BSLEcW;c= z04n?kEoL#rcsPZJX67R1t(~7yR5`&aa`@JEG(ExMloH*h>agB_o+_sQ#h&vWqqrmO zBn!iZ>U8c{eTrSy@ptCy#H{l;aX5{@sq?H0|LzN&h`7M=cqc3#_b;%TJQRU|i-=QBhG7GACnRqX(vB^Jw#vQX6hOdxp^$q)zTm-v9ghx%*iC-^+$pw5Q zo?d2kd~1W6VAyBZiP~4#N}K_UBUe~$Q%jnjbZ*xO0TPMZ_k)JK%vIJXG6E^I=Kx>@ zWse#S7MN(SR~s3@snIDL^eJ{!feIW>yLuZK*;Q6MB>dmW%4x|eA~z(PVnemAvg0g) zi@Dd>VP@u{|8>@qg*FyTuCtGL#Rkjo64K=fLqO6lem#vGH22sUBWnSkq zb)t`xz4Q%*TPuK9RTC@jvg%^mZ9K+ftJgRKchy{MXW5jM91k~2Vg&nHJA;d3F7{rF zMiJ=8EQoCNarB#DYwJZQw*qU-7T7q+$g+qu+u*>DdL33F!_^k`#gIEJxooE_*|06a zvNGeR;db*~7AkJtVb;jGndpk~=!%RN;l`OWalB0H%Y)v?&Z#fpcl1MjK@OybQ$7Qn0FE9fz+AzD9T<$VJw%X$|- z(}}*1SuK(Nh|Ml9VK_l`j+T6~bkJ0pqM2`iL_Uj~jzHdo2`&7du=@PP6o|Y}P|!v# zU=qupprCYoZTg#46vv*Rpo%hWM_fj{`-E*OUx7Z0lwti$BG>jcNxbfuT(Ux?p0e4@ z#D#du8c-Z&*zif7_CI_I^9z42rafb|eap+Z4BS7IBXjZ@%Pb3+lXyJ_h6JMt{lv)U zI6ZCj2^Sq+u#kYKl|59k5NwbRjWNfg+zX*idcmT2J_1``usR_NCWA;S-0~1f1;Qn( zCCT#7s(mX9tqm*?=901+VSe(GrG(-MFx+@dDF!8TjQcO}P5hOQi+O5vq>nKE z!}^)>#}kjhA^$EJz`^#G@j5a6AMm)(5%}>RmSAeE(;ls%R=4wJNQ;l50p zqsw1ImDwo;lk^R1WcqWgr*?;A00!1ED0$)=Ho0{NKu{NG6r|}Jl$Y+XMu7eI7^13% z=Qf#S7H&0+vZ&)`A64A&9%T_%V{(G6_ztqy20t!d8VAU39GEQ~iy`cf9^XO7w-}xN z1n5ivX~SWUs!4#>1gNB8EEoeoT>_NR0Dgo)Zc@E~Q-o0x0OZ#NUi+MHG{jm2C;vd+ ztn?O2dW9gM6haRol%oXj)MqFGb_0-Lw}5(5aBI0t0+fd2Vs!@{*&tCx%H?YU)X)H* z5&*AYX?p-*{4*L{Yl^piRH|zXec`~)9yI_(xCVIJdz(OztbiG(HX63_@o%+93mU~ZliRXgDYaCQmG9a*w$M{QaPpXz6*M? z>&M^+uLx?7um{Eo6XRiqmm@XeF4+e3(Sh-5I@7x_?fCT{m@coxomH|?W2O5!_Astj z_{5Pq%{uM6aB|)f+eT4S$J>=Or%^$z-^KSh9SORhw@+^3b`VzG`_G0y0r zwakq6Jn9aIC^}xhOalxW=y3pGyL#$`qUVuSOAp70xv01PZ9fM$1wK2B;$uCp%#RJ@ zVvL?w<=-MOSI?uXo)`t?K`A1%f2V3b45>=WRK?z-aA_^o5^+`s1p{`H zZyz8$^O}i%#dt$Lqnl2AQH+N+2^{#g5mDVRo2zR#;2?l&ugAATOLWn1ksfrFt*Qb) z|2(Mbomd*aeZw(IdH*S^?ojB`iu0zX;1L>uG>qBii%uZ7L_G%zYjF-@L|MGr7C?73N~q(Symq_#Lz4+#0gz)gpbIz9 zTphKeTxm1*5xhpZqJd?$-gfq`fXG0Ta8P>Kv!vC+rxfbR*i7}srcjDQegMP2D$4PP1Tdl;ufuPq zVJR-h8&+M92CEId8IY%bZw4>bPnft-4vo3mkBgA=kvDk2squf)4Iack@#Ruhi z02>}FCYI;J`Fnl2xKf^5`5zx(H|Ni5@>K{d^vC!QLEt1oS|Z@~=VL^@s=S;b>jQ5? zCj2HkRppiVYs3$)%0C}ffICaF3Bf4P9=j^zdElh#pos8ig}sPYt-~u>^!`@VcL+E$ z(T0qFLXBCqkp@6JfUfZf%%Q*t1TrWvAkO+c@Di!Ax!`Wl#0ZL6IBGV=dbc%BrT~=)5H`e}3QFs1+3PuLFZT zFwK{-AVDdqSRZK?ZULYoL>w#{flZzQFbMNB@g^dw|OuV6CT4AX^ z2gNcI4=Gz=5(x=Wj=#}i_Nc`7v6(UPW^7@BC{cmWVGApW6_1!ntgFBW>TOZ`dgw&? zio9#dagZ&5zpgh}VMSimV8*vbY{l}$B0$*917cf6UbE7&R=nl<^B^{-xp+{S z59W9SRP?ICGx_VTTwJJvDRKgVVnLWR3lQiK1jtAP#s=|FR%(y(;0r_= zkO#*i@055%&Us55(AD5(Tt->eROE(WhG#YvXG3@!t^*sdT#ZLqE_Vitrz3$x>pk~T zvpY8-;vNZ+6`Vzc3!TJu~6E99G1+QpX_)5Gfum#q*k|64E1n?lH#(31L)ilE! za+9EDV_^qeU0M}ZH>YcoAq~xM=!|gRFs~X9;nAISUy6?5yh3N}H$!=i7PU|=G93`@ z$$cyW&^XH6->4Bqb3YIJa?1UB5ONQ$DaMBKXr7V;K|K`BOHTTKHSeRwTJwg+wo zkr8e`A#Rd9`)eXBT*|4sU=;3!eGeGX$c75&z1w1C1dn7lm^c~1&l=x!Bhyodp%eUZ zJ?g>5?%I4y*K6>{8U4(d^%GdTtF~EzQQ;&%Se~f6>w)#+0s=0mNe|xk(p$W^>16+c z8>l6SBPH6JnXQi#?EX#7HvRi?kTdJ>#Q5@Yg>>>%P6N{DMd0;M+J~YK>(oa3H_1%= zkV%5|3Dsg|6U>TEcKd1$5Lpr8OkIu_&j5H00Q?bE zuE%Te3+;8HeLbw?8xR;*4+Huc0;}pFZ8rq|s>f^dFa)rzuWflAQ?!Oo+;^uToL!Fw z^_IHVUykTw`RP_SYoD(?u}!qkcu%a}1bJ^Rnt==g0i#!zOnwxohCna^+R)SEC1;S- zH5BfoO(i7!ytIMR170B}e= zqA@DyV}J{ZrGyv1xtIx^5hEEWueT84m~)pxx>g1zhjSPM0_DC{P|YN`#2!j2QH zoLadkY!_feeFywNeF|dck!z0bxYDR=kKQKn+HKkn$=I9~o|`g(sCL`X(J3JxjvqhP zY~=@HON8eoD`-s}rRg@*vAq6sifh zlvaI=PnWR>fa2vf4&rXvJ(=vhyGAL)qSAO+y0zA!X8PKf1j1hR4VsDMich}TZ7qtaSIdyQwt#oQ*m zasAs^C~)mRKmG*z6s<`;A-gJ1g7;;lolp`o&J$yFn}$W}#DgY0rc&c`g(6In^*ITl zX)Cb7c+yBGIz{msHC}_Qxs$^auwBJzWfS?}voYhj!8kLAq;q@eJ7<~W%P2lj;XBVT z@vJF7&MPDEdo%tT&Y2Ks&X@4hkoiYO^Y6>IfLlfLV1vV~yl`Jhv_-Xu(!pgdug*V5 zpi>LpG`MoY{}3S58K#{D*@K6Vb}St$65%4pi-Fd;v3N&cF!oZj3)}Qz+H9 zwGslEVz&?e;^A>TtsUgTl9ym_5*+E4hiltIeV9+oHYg$8@sS7Jrkzw3INMK2k`A44 z;D3?)#GB9yw_9OA8Xy35Zy+Dp5N_LA^GaoA;Pw@4F}8s`ToF34tu+t#KN^8t>}lz0 zMf8zt5S&wZu|wZt_xE5oiSuG_Mzb}3XG^=RX5&a0{<6Vf=xZjv(2=S|LFex975;5_ zTKUQiP|mb{xjs^fgV*6^`-)XT{X-Edm~s|s~&aj~H-uU5u@ z{_+*d8O?8>Aox<~D8=}G}8oozJydsmz zJau%$TV^LMwX2A(?ReGZdaN--RVMc{59_1HvfQbknQc)65zddlBkN*MyW=*|a%GKI=^Ua3L& zx{BXp_=pN^frvgZ_rWZlPzPbVz6qver}n%(tbI-Xn3ZZph{zxcyS}OxQ?33X+Pgs1 zzxo^lF&cZPA!fHOYz-X-0Q%Fbe|Lwt+@6O952D+MqzHDqQ_7iVe%0*o#)RD2cYWL48 zw}_A9EqGKFD9Yn_vhgJtHO;Kla&FUi;c(R)#|PJ51bkTM98I)N@I!TqxF&^wXgVH1 zrOO*^Z3WJ*2DZqqC7bbB+d$4g>W`fKJ>?;MHoaBac5AlKqb{P{}yOl1Ts77oKgyMbnPZN+yTt#Je4N z%c`GZSjh`LesKHNY}3id8?er#o>JFW6&pM93eAhPrG32VNJXd(`hkGezo^1qCTXS% zfz3S2XkX{SH-*B0xY!XwXJ7#ntP_-1AHNaxI`N)$J7Qe`)z89%w9qPS@j=OQ)IXBz zMc-MV9I0m8t0vzQ>pSs=jmyZc1!3$b6r|1EjI_8M?A%LJdyhK=9r0BnYH8DvuCHG( zwsDC(pv;#fq-s`dy|*#ZED?L4D{hgN$P;;9btoAVd7U!*=`Nx*eg*Pi6?8(M#M?zy zbVI0+*H-Z|cUl2WuDYQfE%s@Y`PR$_q@$0i3~RC^9^A4)Wz^4}HcKt@^p#uv#0dcl z6$M#5ReyQ{5&(NGdKWeqqfeag=wpz~(I~~g)V6;x|Fqqy*xdm-mKxmgyaS)1u*XcK zoB4ZHV;`Yr)Ar4xN=VP&^Ph2#;d#O1SK?L@9~k|L?!p&c2VDUCmvB#MNN&?%1c-1i zK6oV}$LXcJqLnA(L0wLDgq zN|f$#iajFM`L8F_Y+n572xv2KI8MxNsk85+;U~NB6UEDwAsc{EVpB3NFXFoL%9VX{ z3#B4b?7;rr77GR+Rj)A@pLWIWW!G6IzUj&XstxwR0NSHm(WIr)o3N;OE;WFT9;)#^ zZ^YTI*tHhF&qP2sUTx4gAWD4=Zhx4qeUHwHKYbwn3WxMl8!)@vtiv9-F)VVvB|KhutNa@a@mS_%p(e6B??Na#YL;c_^)tjNW zP-Zvi0E2>-VWdCHCEzXieLO-&~}v zrKN>+1PXu)bbHc9%~;IxS}gCugG=_igHf?ZwMQNWJ)l|I4fa!_CqK$(on+!%PaL}p zRYX89-k$#mt#jXAybA9U#l@6fyt<{QAC(uMZqARNMbiSm^T_aw9uq1XzX;jJ5(bGf zp)SlH`$fs4QYPYVpxlJc3$SzZ_tHh5qiQIi8!~KbI<_gN+t}pqkly$e6 zl|63wi02oA$|`W{sPWGt&l+qtkq|#rs8LFdDn~(2gkjuT9L(e_aX;FKKzEk5L3c?<$`KIF{@OoXsY4>-{~6RVNi&419-AvEe( z10zt2!W}6MrS=S&52y~8Kp@S(D5>*l#UPdBbC9}^vl8?uM1~RZm+}8m{4YAT;Y~#U zPTXWMMr6sWOc|{gqeec)tPhb-qTNow-SpfaM0z7RDRG<10Rh!FW)1<^W}l3~v1Luc zU+bYgS4&L0>I1}SS9~6T6YRMXV)i{|+EGbdvawK_jz4Swh!ayFPzh|KMwEt{%o49_A$F_w)j zfhMDFKGyEweX(GwS$>E>Fx-}$6{MV9oWeXaDWC) zwq-q$i)?If07Eq300bLq!Qr;7=2~bRfCIGPWLws78Olhf3~gD-+7~TqwyfUT2OSo> z5)$oM7HR+p$a>OxXghVZ+f<>r*3DV4y>`1zr*NGw&ekwt&&`m8jKd7$dlBQ%N=dDV z#$seanG;H2Uefqu2Y_WWqxJD(7|PV@a{TZx+40DO+9+aUCSQI-GzK!Yfh!Q+)d)cr z4Zk#Q(^sB2td0Fpaz^tqslEsFBT=N{ntMP$2m$6Cj?>z=s)nKS91lL^d5rl!acmjR z+bDd`_ssEh1TT%F((jlkHj;Oj`pemfZjuVPM{d)nueeY91DR0-!?w8tR3&f9ObU%W zE@jR1ohBJ!%q$?Haql%pA5Fa-<{XUd@MML9PRBE@JWq^xky4YA;B`Z9f zfB9RyOyM7}UVn?;sk~m|%p+K^;f+R}ihyg9(Jy|Dv8?B<75&rAD3atAyZ#dSWU$81 zGTXIC`E-kZ#8K)Il3es}Tre(7#WCLgW5RbLuO3nWvD|#@GVP@5(;IW2Z0~o7y2$87;)kiM(lNvn|-1FBvwG5rV{~N$^5296<@) zMt`@`T+-f}$(PT}5O8R|T)}*N4oHv~I0>WrQx+48C-JaiLnCuBJ;mWkkW;~^#EVHh zD0mzV?w(7S4{7sY5SmN!sx5wz3-XknIdOw~GH+Sq5mgtPx+w_6?2`4#$O)kOkf&5c z41RYCAa9Jb7k`!Jmgy zMfJ#CvHTO>)N&TnNZaA#Jq6?d1y7RoHI2|P&o=Fi`e)uNw{tn}>Epb+!7c6+XMLP; zjicJ-7D-8R5lNC)+@{Bvheehgy8qW%8y<@ACb}SsBoaM7<)MM=i-HOf7YRJx_9+jn zl6i)%VUm*_ykeR095$rSsq^fmCjes~GT=kef6h;Nv`J184EG@flB_pfzGhoaZ_(^C z9^2I$H68&hUolc6Bwr55A-ak)I)(+n&8abSB)#=v#XCoMvLMcSZO=6w2x%4dF0qe3 z#B7Mp)`;Ieu&%MwR);Jzo>qcL+k z_k!dZ!a{GH|LNAEPykIAX0pVH1Z7~ze@oX_Z|obv(wlyo}jr-bt= z{Zw_Hqn{Ax3Hqtv{DXdKISXgJx}*2DaEvb zG)L!6Eaw@Njf!VbU6l%h2^p^}A;#%dFo8T+csyDg%C|Ix1qOrtG%@;GYII^tInJp# z$9qc_jjl+tFlH$*qX0P=Gj$03n+TGuw-O>Q(M(TmiBc~aXXZj5pJX3psS(o2uB(w4 zt-?-DCD+GcG=GSEta3V{KFJ_+>A}=hD$%xu;#`T5x!|nciGj`n3QY=_jCtmTYFGfR zjGPo%J?X5*mbxg>DpMy~*HN#+Z)sA5-8qoh zj)qS9HS3;?D;#m+%yizw(jM!WWHHeQP>KwxH6RJsmP1v-!@-C_|H9J^;o7!@04QIx zpGPiV?fvldOzVGcf{T@z2Zyn}@ywDjGnH;i$mi+rz-}wXeG1O)y<0$SE2-`MELb(D z!e;9S%0|4Rhj#T)wxLglOJENr7cc7pRA9^Y0|cSpZP_KX5H`bdC)z_ffdtQ~QxSjK zJ0J*OMvhP!_fXVC>k#EZqBTW%o@i~QB)H*weO)-R5pObhfC(?NlV~H^q)n2vy6L>A zlL@`l@2)oKInyv07;z4?16lN;r01j)j3yF(&7gezr1~aC-!x{P2VYN&xS7ahPNV|Q zP?ZU~$fvG)kkxc0Q)|+#B4XBl_-;~~RxY0eW8Cj97I~1~K`_Q&!5E{uw-O+@sW0z~ zfmytwFwWqW`j4Z2v8T>c51*qcltbS>DWT--HYm}iN!m7urFdRJ*+WNdAYj-#;0O*> zfJVj_5WmpY0{J%fHd+6)0#dYmBuk2XTS%Ltg;b|Ps)7I}Qyq#HG7IY@=4rv(Qf7g! zF{5eBa6WI$tfiGQi-h(wVn7xTkj)uT*qn7|i!{eu(*JDEQJRn72yaW0{Lh*L2Q?@O z%9VxKx{%aP?J?gI))_pqR$(bsik4E7+EcAad&Jf(9$x9P%n5ZSo{mXClt|THe^-Re zXqu4MC*t1Jlsz1 zAM)c@VB~1%)*Oi6riedg^0IF$@dyp~R>GKBK~`D2wrJ~%%?WYcn`+i*!gdufJE%M2#df9 zEK_SBoT7aew`!ogwCQKe`UY6w1#)6Y1e7fK_D#4SE5!OtVrkPymbpcvt(WR1KC9Li9e|{<}+Kr14DaQsSB5!z4n;^<)oF6Gr~g8#1mfn|2Pa z(&miZ-dK%|ndyi#<76Uy(jEF~IPpfJ#fJAc$-DeHy%WP~SxRgc2^_gp32UhNYO{YVEmC$^%%yx=qfD zSl@0C0v5aT^x>P((}QSyi%1I{2};JyUUz6vE;-HkCCN$i*tQZWXtEL;nY6E=Z?A?~r5b4x`w-juP96-Udm=-+kq~+cS zxy!XYf+{$G*c;wyNyFRD0R-scN^<$hoslm-)t@Lm1iq<-=^sG}Bb5YB3qtDWKq#91 z2^oz&*KY{8Lh*#&|CALrB1*~%@1h8^-J=QC6kDFkuf|idYD44=YNW+e-AAnnCIB&u zlyZ1T*8*`6>WslujbeyV75ve(hU7yPn!@}7tY>PAABe@kr#jxY`V4QzG(rNi?N?aR z;Ab=5O2-DPAJt@9o*%*J+!J2HzJ%=yS=AIt`TTs*lu=sJ8vjbF_C+${FgMm0IpXdP z8=&T9n_j)h#RfZ0Lcc-ajh)v_Iz59}bJ}H})DTQA)oj%drTnZxvTri>HOCokB-~yj zH;j@BQhcCZmsxA4Riq$|=^4|byLsB3HDc@>UZKmj{P6yYZFt6LCR)wqmgZ3QZXq1Az2`PH z6OXZwGvm}C=M0)GcKxBFRQvd&`SH~EKGM_i7_{uDcs!T4?9&t~6iI#c5b&ra<&8Y> zSLB?uk>uEjQ?ImK=R+&-JC0^-_egaot6R9?_dhQAmaGak{HY&_f%AB8OC89*8PJ6G zgq$;gxPytd^w4Z%HK(u60H-5>jWNj{Z{(IpT zB+**k)elFnXNvB?rI>8Ccf}R(mu!48&j!mEgSi+BaR+}P!qcxMr>Unv;Tg^!Pb%Qo=574pt;F?SIz9_>HM9mf~( zKNZ8f$Ei;+U(3Lk&Zfn@Pp}W^Wo_|L9esGz=%*ix+cfQA@*m=hkN2K2QRi#kQdua5 zea)lrXz0?fc?fHJQ0)F12c~(V#S-3JnJp$P;kDV=gJSs--YTl=f5?W^A4LjC_D2Z~0)!Z|ls9L1V|~q1R2RR8mh#4y(}aZGFtKwwDz{}l&>&_& z@bz5#x-9d`@}b$KZ8Q*9Li-|?jxRs$i&jaloAC+R$=BP&Xp~#Jv zWTRhJJK*3nl340vfv^N zLycn!@Ld|;qVaNWt6V^0wB1eu3i^OLkJe=Ts3-7ZCJ$9Ei&x9}SPKR;w0{P|3R_Vintsb8%0|g}956t&0sAkcANMT}C?9~m;am3L4toWkkzaqy zLoJQcTQo?mhq}v7!*Q6c=Nh%rZ**!z5SH2(i~j?J)cwmKC&ZC^HYZ^{+-|3-9Py!4Od*-542R=U4vxweW`=rxB_El=U zZS)!v&1MbN$zz1Y2f0t-M$#i$-B?1;^1!NxvptRch`JueT4d3LOFviLrt%oXnyX;N z=Bg|5R`K5Kb*>0n&D*k_xuV}{7{P|3GD*q}$hvD}OFV-tSx>Kmw_^-@GHr~NC1S^F zT&|;eLX(+VOOttkaINN*189ce^@0r9F<$9!Mjrf^eaC|nhvb1Y?K!erJo+T)p(~I^ z21+#QtmxCm%z?BYu*QQTwhRX>(YB5X^L93={Xth{h4nigp1kO5N*fPJIUK`=`J9Y1 z#`t-(c6vIKj#8%IhNx@3f$60U>gj~&^C<&SCXFqMg2j+*xcWjU-^2Fj7gRXpdtRyg zu)U}-*}j=!PM7NMB)h}HZ=6Hm6BgM(at@#vyT(*)<^kA&(!@9VwMz!)+o%QGA-F== zzvmVE%p*vIWHabJ$#rBe0-R{QR#-&pJm*vFZb-F`NrO62YrcYYv8%FFx6|G?307+m zI}oA`^^^s|jhdTg!3(L&1W^*_k(lX_w72f%qW&5lJ+uX)3I*f}NJ|TX+f_ROj6ze5XW07uWjVksT0OG7&T%L07N$jvUcIG&tv0MJAINX zK`e(@5>Fj8+x5pbk=rz5mJWFl$~K8I0Pju=#Q!M;#^i$(eZ$A6i%)vaPRhxcd774% zoE+`rH+)1&q&?cCk&FJnZ3KF3CMwYON+k9U^x6pYC!!?@gMPJy|F#k6{;MV#M{3%6 zmw%yPj6|+Fnng_*aro9g?ZDO+!j zEZ+*#%p?S^Z-snc3xQe=-ikjy$iz?wkLBAC_zCZ$@dF54b?^>+CIWDK+nx_bVB9u9 zcEF;0J3%Z6yxGPhL*6f7KHK5oh)O0^#@%SS`6j8{Zt7UT99_2a6$-C)fQd&tct?I~ zKND?#h3)@V1U~x}dCo>)A3@&R&lc`PMXCbOVJ9k57lA1|c^7_t9}|an0_7kAC366& zh`JA~1KXG`+U((rm3?@Zn6F82;b;aN({&RIMJ};zk0R&C?`YuUilH6EBxAhY zrUe?fx5T9L8DjNrQ`&cM_PCe->Thek9~jOR)YrC8pblBTnv1XUc;)i*R#S#=^(5)5 zxg$T1M>FMjf#=1Qv(Nw3AV% zzJ;WFfNx-mfdaDaoSsAN;QJv#4{JpJB7IMVmi(kf?ryUs0Y5{ZSaA9&E?Nw@3LR z-mM*Tv_8g5DoVV=e4Lk8lxgCFKY0)3ykpa!JW{E&7S~B#U+$o-Ip#3NFj?v{TX)MA zuTF4_66u)o7dI#h-pxG8t4A)H|G)OdG!6XUzW4~TPE`ai~e9%RI$UFLS>N73yHk1M@?CPo4}YY>>a*s<~o%=7rH z8MthHmB(9}zX!e;q}@rSDXi8afB{UU{$#Mt7w?nC)D_~Y>JdGCFn`s?G0=REChYgn zLKh=7Li|yep9hEbg{mbD^T(b;M51ms0iT>kc@Rh^rM8L35O$TP$m*Z(C^$BK>IzVO zk)a2R=CV2ho+o3rDw`FOn<~0ORkgo{03aRZ=Y(MLV&2e?+cY5yUTm-7p4dL|;u?<% znA$<{aV4q4JZVs$jZ~jgqQiCU7SCtC?U;gORPpz>Ra`-ZH%8&87Lv)jq{QMg^J&Uw z&U9+~-~Ikw)t-oUR-u@4o)~BEw;9Tgdt|^InymgR<14`mIyfC{#wWr3dy0ROeSHAL z15%BS63Pu;v0`1SUq;$SY$GoKOM1pq$MzEqZoth$&we7|2Co_VSB7i^F;w*!8j&v# zU@2GUBK%QH_Y+^-0898u>_MJQMiKh|WQsjCu*MYqJgPxCaav}84c`R4xu<0hon4>=Rvg(+hlOdEixANe*1br~mOD!#}s-kTewKXM{qNQ!B+FGJbb(FSgo2twtx&P<6Gehdre){=*e&5G` z9*_6D&ij4dXJ78QXS=?ehO@n#H*n+Gy0@RWe%t)L`I&_@n>*%FW~GjZ$Tx3p{Vp$# z_9uE%>*R^L&*5UyjD@Exdt0RP19Gk@t)21%a$FXz2gD?EjZMC}nRnBkL}p??(drj- z@2H@L3e)~2dXj&B5B&+t>}@U=s)L;oO^ANX2{p zck>FRt_Zqo4i0*47O_cR$O|j?g~;1ad#C31<`m4dR-*4+bF*p-xm?9{4oHsq(t2mf z{nLTHZR_vyh%)b~X0j;`v!*Gng|}|*t=Po?-JGaY5r=eh?U>0EWm1oZGo|8sRyN0^ z2gJF=QTN3p6mdtFIR3tvZUS-riRS&G>aS+gmmNibs`jneoeRR=m)kbr1^6D@p!e;VOXDMwi3?<>IU)@i;AHA0=?fdWBxRNhzT*==!l-r~#sI|=VhMH|3 zRZ#Ox=5^fplj*09)6!~kn~$hnN$q65If#3$Dya*Uz2aIWwH7x8J&r`FtX5TKi@?h2 z3+63@%(i`%Rjz)0zeKTJuA+`mD$W^1o<$jX7BRqViw;l+sY(m6sk%B?;UdWD>QhRF zm>8rUQRa&JHPlYZcrmVqy4XCTH`^p@sG&6;?aebgiH?;PIk1Vl6;oa96YGe2!RoM( z&li9=5^fD@j9IVNAtY}N_Y}Ta~ zo}p{O#+Y8nVn+PnEk4yrh)3mv-q_3WgxFhC{Z;u|aGY+sGT&CYwyG-1T~RHBR93Ui z2~m9%)1e?+N~k(jsoMW>-i9pK<@MpSnOKniM?G#9-gVXP=DXdv*|Dx#-TW1Xsdd#l z^%q{D z=hU=?*H;^;rjED8la17_rh7k#^^Md}WxqJsNKNId#a$xEt*v5Vgu2D#HDAIeOst=6u!5&ptV_?dqhnRQd$$~w4)a(YzCi69ebzG4Ub8y`9mwt=e1P3 zn0K@?+g@p@Zd1%kB-cc>Qp0hb!zs&ItyJz=Y-zS_Z>46MO_5i`kap@C#_PA+sU4Kx z1y?TBp>OH+s2Zm%6k8vqZ%Gj!KC1Rs%1FD=vP=`o)dKq+(Yd{PPSa8ZQW)~ll$rYIkY8IP%*L(@3P&1_8qt&7Pe-{sF!ibh-HsgY&xUF;N}K1Mc` zG~}lKPHL|fJ00@0S*|>8$}aB4aWbSWmIPEA(jc(f2rFu}R zMzHgzXwX^hPG^|YfNbro_6c6vK-Q$&vFV3%iJ@Fw zklhGp8YiN0t+RS@)XhM~5)<)@NrH0KF;8W)(ye3U2v0;Rp&pP_U%pQ89+57Eu9-{L z!ja0>GVLBtr6w~PJ&`dayQzJ+5@VhW>Iqar3GH<|O>!x-vD<3JgyWP}W#af0_r0z3^CH8g&PCg1P zr*@iQx?R;}t}D&ujOAr}HOy?uAk&O(3tVX`^QK{_>_T1A#l}Ua3sS{@;tVy5A7a#gP^MG`h;Rj=&K%3l-ssy{nUPD zbJt^vm@+_3VS(Y70cvsOCphjY`+M1-vZyJy{MHXr$0_5)_(AGK<%sxXkUGYkd{_}} z;?>j^DSkwFnKA9)8u>7SBU7ik#Bx~e5-&Ey1O3e6mw46R+zG?B1l7MrxKu2)XcpmK zH1k8D&0w{OIoFq?8iUnS%5>3mh&n;3FT@bFyYiE`K7{U(xr(9cJywVvL)DJT3!?2X zwM*^e9Ov|;K%V?}x6BfI>UEk#ig;Z^T1A;AlB2%?P!5i|5MyW%_5i#1E%`7|x9Jcf(*B zseV6&);hys^0FV!qZ&1&VAsOYr(JZ-ph&Q<&c&{RtH+@Bd0mmU?DnkNGv&FSG-Cnf zb{Wh@D=$};+BQVm$b-=ZTm+2R=np4|Clb_Zk6yN*5Oh1>b``0_hM$tXKcEEeUGXuoWoE##+`0;3*>j-TvHHvch@}#EFXuY6GrTZ*MV+ zq6D>WjQ||6bAVGMcas{&qz(0R7jv;U-+&mUMwt&`SU5^uWPY2Q8s#MzzWHC$Rd_DJ z`1VT?F(^&^l_>+%zMl5p`X#}7N6N^m^ z1krMg8rS44jqWk(Bbv4xx5**$tjnHm=`!ms_7ryY$Ubq?7j!?FW7PF#Hj24owGGkz zSY>=6<|V32%zHex`Ik!B^5MaVvGVEIW7(&D$`nAFGZvz5S6W9;*)Y=|S|3 zV)IhDYJZ#>Zr+c|bK}&ZrneOF{W!I;X}4kv7_UC7nfy+R%~RBfpei3wy+6rg4uO&5 zn%NC{q{+`^R9LxF5#LTx>r`x3#GP|4*)U{PrmBfmjyg?T3*9@lC??&QL$rsT63

    Xt;uS2wqkll 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

    gW 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 delta 274279 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 diff --git a/posthog/user_scripts/v0/aggregate_funnel b/posthog/user_scripts/v0/aggregate_funnel index 04454c7371931d255eb56fb38e3c04159c329622..0605040d162ebda124b17c7e9733c137af6e6111 100755 GIT binary patch delta 162193 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

      Xt;uS2wqkll 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

      gW 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 delta 274279 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 From 86e70e110fa1cb02339f37b371a3a39ff1eda399 Mon Sep 17 00:00:00 2001 From: Alexander Spicer Date: Wed, 2 Oct 2024 02:28:53 -0700 Subject: [PATCH 05/10] libc6 --- docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh b/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh index 187ec4269a15d..b38d1e0a1b729 100755 --- a/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh +++ b/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh @@ -3,4 +3,6 @@ set -e apt-get update apt-get -y install python3 +wget http://launchpadlibrarian.net/588931980/libc6_2.35-0ubuntu3_amd64.deb +dpkg --auto-deconfigure -i libc6_2.35-0ubuntu3_amd64.deb cp -r /idl/* /var/lib/clickhouse/format_schemas/ From d760efddd0cc73456e49ddd919cb3afbc90c5baf Mon Sep 17 00:00:00 2001 From: Alexander Spicer Date: Wed, 2 Oct 2024 10:11:41 -0700 Subject: [PATCH 06/10] python 3.8 --- posthog/user_scripts/aggregate_funnel_trends.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/posthog/user_scripts/aggregate_funnel_trends.py b/posthog/user_scripts/aggregate_funnel_trends.py index 0aa96b7a19b96..2eae482d7f1cf 100755 --- a/posthog/user_scripts/aggregate_funnel_trends.py +++ b/posthog/user_scripts/aggregate_funnel_trends.py @@ -1,8 +1,8 @@ #!/usr/bin/python3 import sys from dataclasses import dataclass, replace -from typing import Any -from collections.abc import Sequence +from typing import Any, Union +import typing import json @@ -40,7 +40,7 @@ def calculate_funnel_trends_from_user_events( breakdown_attribution_type: str, funnel_order_type: str, prop_vals: list[Any], - events: Sequence[tuple[float, int, list[str] | int | str, list[int]]], + events: typing.Sequence[tuple[float, int, Union[list[str], int, str], list[int]]], ): default_entered_timestamp = EnteredTimestamp(0, []) # If the attribution mode is a breakdown step, set this to the integer that represents that step From fcebd85b7addcfc048cd7b658c4bc9ebc944f477 Mon Sep 17 00:00:00 2001 From: Alexander Spicer Date: Wed, 2 Oct 2024 10:27:15 -0700 Subject: [PATCH 07/10] python 3.9 --- docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh | 5 ++++- posthog/user_scripts/aggregate_funnel_trends.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh b/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh index b38d1e0a1b729..1128061c84482 100755 --- a/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh +++ b/docker/clickhouse/docker-entrypoint-initdb.d/init-db.sh @@ -2,7 +2,10 @@ set -e apt-get update -apt-get -y install python3 +# Necessary because clickhouse runs on Ubuntu 20, which has an old glibc and an old python default +# Can remove when we upgrade clickhouse, as the new images run on Ubuntu 22 +apt-get -y install python3.9 +ln -s /usr/bin/python3.9 /usr/bin/python3 wget http://launchpadlibrarian.net/588931980/libc6_2.35-0ubuntu3_amd64.deb dpkg --auto-deconfigure -i libc6_2.35-0ubuntu3_amd64.deb cp -r /idl/* /var/lib/clickhouse/format_schemas/ diff --git a/posthog/user_scripts/aggregate_funnel_trends.py b/posthog/user_scripts/aggregate_funnel_trends.py index 2eae482d7f1cf..cde3a30928584 100755 --- a/posthog/user_scripts/aggregate_funnel_trends.py +++ b/posthog/user_scripts/aggregate_funnel_trends.py @@ -2,7 +2,7 @@ import sys from dataclasses import dataclass, replace from typing import Any, Union -import typing +from collections.abc import Sequence import json @@ -40,7 +40,7 @@ def calculate_funnel_trends_from_user_events( breakdown_attribution_type: str, funnel_order_type: str, prop_vals: list[Any], - events: typing.Sequence[tuple[float, int, Union[list[str], int, str], list[int]]], + events: Sequence[tuple[float, int, Union[list[str], int, str], list[int]]], ): default_entered_timestamp = EnteredTimestamp(0, []) # If the attribution mode is a breakdown step, set this to the integer that represents that step From 32f83a0f4b0917bbcfd167eb70f318474150e85d Mon Sep 17 00:00:00 2001 From: Alexander Spicer Date: Wed, 2 Oct 2024 10:52:52 -0700 Subject: [PATCH 08/10] rerun versioner --- posthog/user_scripts/latest_user_defined_function.xml | 2 +- posthog/user_scripts/v0/aggregate_funnel_trends.py | 4 ++-- posthog/user_scripts/v0/user_defined_function.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/posthog/user_scripts/latest_user_defined_function.xml b/posthog/user_scripts/latest_user_defined_function.xml index 8aa8449bf1a54..9a0b6001786fa 100644 --- a/posthog/user_scripts/latest_user_defined_function.xml +++ b/posthog/user_scripts/latest_user_defined_function.xml @@ -1,5 +1,5 @@ - executable aggregate_funnel diff --git a/posthog/user_scripts/v0/aggregate_funnel_trends.py b/posthog/user_scripts/v0/aggregate_funnel_trends.py index 0aa96b7a19b96..cde3a30928584 100755 --- a/posthog/user_scripts/v0/aggregate_funnel_trends.py +++ b/posthog/user_scripts/v0/aggregate_funnel_trends.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 import sys from dataclasses import dataclass, replace -from typing import Any +from typing import Any, Union from collections.abc import Sequence import json @@ -40,7 +40,7 @@ def calculate_funnel_trends_from_user_events( breakdown_attribution_type: str, funnel_order_type: str, prop_vals: list[Any], - events: Sequence[tuple[float, int, list[str] | int | str, list[int]]], + events: Sequence[tuple[float, int, Union[list[str], int, str], list[int]]], ): default_entered_timestamp = EnteredTimestamp(0, []) # If the attribution mode is a breakdown step, set this to the integer that represents that step diff --git a/posthog/user_scripts/v0/user_defined_function.xml b/posthog/user_scripts/v0/user_defined_function.xml index 8aa8449bf1a54..9a0b6001786fa 100644 --- a/posthog/user_scripts/v0/user_defined_function.xml +++ b/posthog/user_scripts/v0/user_defined_function.xml @@ -1,5 +1,5 @@ - executable aggregate_funnel From 403ac62fb8de936ea0bdb6d57070be4ac868131a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:10:39 +0000 Subject: [PATCH 09/10] Update query snapshots --- .../test/__snapshots__/test_funnel_persons_udf.ambr | 6 +++--- .../test_funnel_strict_persons_udf.ambr | 6 +++--- .../test/__snapshots__/test_funnel_strict_udf.ambr | 12 ++++++------ .../test/__snapshots__/test_funnel_trends_udf.ambr | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr index eb95b923f5929..90e66603e5963 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_persons_udf.ambr @@ -8,7 +8,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[1] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -81,7 +81,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -154,7 +154,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr index d82701546b9ea..1dd99c28faa3a 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_persons_udf.ambr @@ -8,7 +8,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[1] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -81,7 +81,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -154,7 +154,7 @@ (SELECT aggregation_target AS actor_id, matched_events_array[2] AS matching_events FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'strict', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr index 8745e81203e3e..ca74dfd1d449e 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_strict_udf.ambr @@ -1352,7 +1352,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1420,7 +1420,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'step_1', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1495,7 +1495,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2295,7 +2295,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2371,7 +2371,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -2447,7 +2447,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'strict', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr index 07c6a328a4d04..7217e127db631 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr @@ -7,7 +7,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends_v0(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'UTC') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown @@ -52,7 +52,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends_v0(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfDay(timestamp), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'US/Pacific') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown From 6d7dec4ead625735f8a0d8045774279d68d04af4 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:20:24 +0000 Subject: [PATCH 10/10] Update query snapshots --- .../__snapshots__/test_funnel_trends_udf.ambr | 2 +- .../test/__snapshots__/test_funnel_udf.ambr | 32 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr index 7217e127db631..bded4b095c3f5 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_trends_udf.ambr @@ -97,7 +97,7 @@ if(ifNull(greater(reached_from_step_count, 0), 0), round(multiply(divide(reached_to_step_count, reached_from_step_count), 100), 2), 0) AS conversion_rate, data.breakdown AS prop FROM - (SELECT arrayJoin(aggregate_funnel_array_trends(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfWeek(timestamp, 0), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_trends_v0(0, 3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), toStartOfWeek(timestamp, 0), [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, toTimeZone(af_tuple.1, 'UTC') AS entrance_period_start, af_tuple.2 AS success_bool, af_tuple.3 AS breakdown diff --git a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr index 7b910d2701701..fc27315723526 100644 --- a/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr +++ b/posthog/hogql_queries/insights/funnels/test/__snapshots__/test_funnel_udf.ambr @@ -19,7 +19,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -67,7 +67,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 15, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -143,7 +143,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -217,7 +217,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -278,7 +278,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -337,7 +337,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -404,7 +404,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -471,7 +471,7 @@ FROM (SELECT aggregation_target AS actor_id FROM - (SELECT arrayJoin(aggregate_funnel_array(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(3, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -553,7 +553,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -609,7 +609,7 @@ rowNumberInBlock() AS row_number, breakdown AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', [[]], arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, [], arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -662,7 +662,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -730,7 +730,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'step_1', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'step_1', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -805,7 +805,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, ['Other']) AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel_array(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_array_v0(2, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -878,7 +878,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -954,7 +954,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown, @@ -1030,7 +1030,7 @@ rowNumberInBlock() AS row_number, if(ifNull(less(row_number, 25), 0), breakdown, 'Other') AS final_prop FROM - (SELECT arrayJoin(aggregate_funnel(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, + (SELECT arrayJoin(aggregate_funnel_v0(3, 1209600, 'first_touch', 'ordered', groupUniqArray(prop), arraySort(t -> t.1, groupArray(tuple(accurateCastOrNull(timestamp, 'Float64'), uuid, prop, arrayFilter(x -> ifNull(notEquals(x, 0), 1), [multiply(1, step_0), multiply(2, step_1), multiply(3, step_2)])))))) AS af_tuple, af_tuple.1 AS step_reached, plus(af_tuple.1, 1) AS steps, af_tuple.2 AS breakdown,

      W6-f>0|Nw?wKNV@TE#wBGKXtyIUkQ*XG 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 S5rpNaIAQrIZo|fHIi!{h0%vF-{|mGQ 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

    W6-f>0|Nw?wKNV@TE#wBGKXtyIUkQ*XG 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 S5rpNaIAQrIZo|fHIi!{h0%vF-{|mGQ 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