From d35f67ec53d369df51597acea9cecb67b223ded0 Mon Sep 17 00:00:00 2001 From: Tiina Turban Date: Thu, 21 Mar 2024 21:52:15 +0100 Subject: [PATCH 01/16] fix: batch export PG form checkbox initial edit state (#21088) --- .../batch_exports/BatchExportEditForm.tsx | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx b/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx index 7fbbc8cc29d69..b015659cfaef1 100644 --- a/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx +++ b/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx @@ -375,17 +375,21 @@ export function BatchExportsEditFields({ - - Does your Postgres instance have a self-signed SSL certificate? - - - - - } - /> + {({ value, onChange }) => ( + + Does your Postgres instance have a self-signed SSL certificate? + + + + + } + checked={!!value} + onChange={onChange} + /> + )} From fa5a1d61029bea66f91f237a47ce9f72808eed1b Mon Sep 17 00:00:00 2001 From: Marius Andra Date: Thu, 21 Mar 2024 23:55:28 +0100 Subject: [PATCH 02/16] feat(insights): string breakdowns (#21023) --- frontend/src/queries/query.ts | 8 +- .../views/InsightsTable/InsightsTable.tsx | 3 +- mypy-baseline.txt | 14 +- package.json | 1 + pnpm-lock.yaml | 8 + .../insights/trends/breakdown.py | 115 +++----- .../insights/trends/breakdown_values.py | 23 +- .../test/__snapshots__/test_trends.ambr | 260 +++++++++--------- .../test_trends_data_warehouse_query.ambr | 16 +- .../insights/trends/test/test_trends.py | 4 +- .../trends/test/test_trends_query_runner.py | 19 +- .../insights/trends/trends_query_builder.py | 10 +- .../insights/trends/trends_query_runner.py | 28 +- 13 files changed, 234 insertions(+), 275 deletions(-) diff --git a/frontend/src/queries/query.ts b/frontend/src/queries/query.ts index 78778cec4322a..f866b2f336d31 100644 --- a/frontend/src/queries/query.ts +++ b/frontend/src/queries/query.ts @@ -220,7 +220,13 @@ export async function query( (hogQLInsightsFunnelsFlagEnabled && isFunnelsQuery(queryNode)) ) { if (hogQLInsightsLiveCompareEnabled) { - const legacyFunction = legacyUrl ? fetchLegacyUrl : fetchLegacyInsights + const legacyFunction = (): any => { + try { + return legacyUrl ? fetchLegacyUrl : fetchLegacyInsights + } catch (e) { + console.error('Error fetching legacy insights', e) + } + } let legacyResponse: any ;[response, legacyResponse] = await Promise.all([ executeQuery(queryNode, methodOptions, refresh, queryId), diff --git a/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx b/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx index d426ca87f525c..c6d037c3d1792 100644 --- a/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx +++ b/frontend/src/scenes/insights/views/InsightsTable/InsightsTable.tsx @@ -3,6 +3,7 @@ import './InsightsTable.scss' import { useActions, useValues } from 'kea' import { getSeriesColor } from 'lib/colors' import { LemonTable, LemonTableColumn } from 'lib/lemon-ui/LemonTable' +import { compare as compareFn } from 'natural-orderby' import { insightLogic } from 'scenes/insights/insightLogic' import { insightSceneLogic } from 'scenes/insights/insightSceneLogic' import { isTrendsFilter } from 'scenes/insights/sharedUtils' @@ -157,7 +158,7 @@ export function InsightsTable({ } const labelA = formatItemBreakdownLabel(a) const labelB = formatItemBreakdownLabel(b) - return labelA.localeCompare(labelB) + return compareFn()(labelA, labelB) }, }) if (isTrends && display === ChartDisplayType.WorldMap) { diff --git a/mypy-baseline.txt b/mypy-baseline.txt index f0a464d26c546..9d5fe48cb5777 100644 --- a/mypy-baseline.txt +++ b/mypy-baseline.txt @@ -346,20 +346,12 @@ posthog/hogql_queries/sessions_timeline_query_runner.py:0: error: Statement is u posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_type" [union-attr] posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_histogram_bin_count" [union-attr] posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_type" [union-attr] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown" [union-attr] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Argument 1 to "parse_expr" has incompatible type "str | float | list[str | float] | Any | None"; expected "str" [arg-type] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_type" [union-attr] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_type" [union-attr] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown" [union-attr] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Argument 1 to "parse_expr" has incompatible type "str | float | list[str | float] | Any | None"; expected "str" [arg-type] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Statement is unreachable [unreachable] posthog/hogql_queries/insights/trends/breakdown.py:0: error: Argument "exprs" to "Or" has incompatible type "list[CompareOperation]"; expected "list[Expr]" [arg-type] posthog/hogql_queries/insights/trends/breakdown.py:0: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance posthog/hogql_queries/insights/trends/breakdown.py:0: note: Consider using "Sequence" instead, which is covariant -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Incompatible types in assignment (expression has type "float", variable has type "int") [assignment] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Incompatible types in assignment (expression has type "float", variable has type "int") [assignment] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment] -posthog/hogql_queries/insights/trends/breakdown.py:0: error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment] +posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_type" [union-attr] +posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown" [union-attr] +posthog/hogql_queries/insights/trends/breakdown.py:0: error: Argument 1 to "parse_expr" has incompatible type "str | float | list[str | float] | Any | None"; expected "str" [arg-type] posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown_type" [union-attr] posthog/hogql_queries/insights/trends/breakdown.py:0: error: Item "None" of "BreakdownFilter | None" has no attribute "breakdown" [union-attr] posthog/hogql_queries/insights/trends/breakdown.py:0: error: Argument "breakdown_field" to "get_properties_chain" has incompatible type "str | float | list[str | float] | Any | None"; expected "str" [arg-type] diff --git a/package.json b/package.json index 770be74997198..79946a087fbf4 100644 --- a/package.json +++ b/package.json @@ -140,6 +140,7 @@ "maplibre-gl": "^3.5.1", "md5": "^2.3.0", "monaco-editor": "^0.39.0", + "natural-orderby": "^3.0.2", "papaparse": "^5.4.1", "pmtiles": "^2.11.0", "postcss": "^8.4.31", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f157ec8b039e..7fc1d7cbd22a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -238,6 +238,9 @@ dependencies: monaco-editor: specifier: ^0.39.0 version: 0.39.0 + natural-orderby: + specifier: ^3.0.2 + version: 3.0.2 papaparse: specifier: ^5.4.1 version: 5.4.1 @@ -15917,6 +15920,11 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true + /natural-orderby@3.0.2: + resolution: {integrity: sha512-x7ZdOwBxZCEm9MM7+eQCjkrNLrW3rkBKNHVr78zbtqnMGVNlnDi6C/eUEYgxHNrcbu0ymvjzcwIL/6H1iHri9g==} + engines: {node: '>=18'} + dev: false + /needle@3.3.1: resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} engines: {node: '>= 4.4.x'} diff --git a/posthog/hogql_queries/insights/trends/breakdown.py b/posthog/hogql_queries/insights/trends/breakdown.py index 45a3a8421e8d8..bde2cd807b6a7 100644 --- a/posthog/hogql_queries/insights/trends/breakdown.py +++ b/posthog/hogql_queries/insights/trends/breakdown.py @@ -3,9 +3,7 @@ from posthog.hogql.parser import parse_expr from posthog.hogql.timings import HogQLTimings from posthog.hogql_queries.insights.trends.breakdown_values import ( - BREAKDOWN_NULL_NUMERIC_LABEL, BREAKDOWN_NULL_STRING_LABEL, - BREAKDOWN_OTHER_NUMERIC_LABEL, BREAKDOWN_OTHER_STRING_LABEL, BreakdownValues, ) @@ -19,6 +17,10 @@ from posthog.schema import ActionsNode, EventsNode, DataWarehouseNode, HogQLQueryModifiers, InCohortVia, TrendsQuery +def hogql_to_string(expr: ast.Expr) -> ast.Call: + return ast.Call(name="toString", args=[expr]) + + class Breakdown: query: TrendsQuery team: Team @@ -27,7 +29,7 @@ class Breakdown: timings: HogQLTimings modifiers: HogQLQueryModifiers events_filter: ast.Expr - breakdown_values_override: Optional[List[str | int | float]] + breakdown_values_override: Optional[List[str]] def __init__( self, @@ -38,7 +40,7 @@ def __init__( timings: HogQLTimings, modifiers: HogQLQueryModifiers, events_filter: ast.Expr, - breakdown_values_override: Optional[List[str | int | float]] = None, + breakdown_values_override: Optional[List[str]] = None, ): self.team = team self.query = query @@ -70,19 +72,15 @@ def placeholders(self) -> Dict[str, ast.Expr]: return {"cross_join_breakdown_values": ast.Alias(alias="breakdown_value", expr=values)} - def column_expr(self) -> ast.Expr: + def column_expr(self) -> ast.Alias: if self.is_histogram_breakdown: return ast.Alias(alias="breakdown_value", expr=self._get_breakdown_histogram_multi_if()) - elif self.query.breakdownFilter.breakdown_type == "hogql": - return ast.Alias( - alias="breakdown_value", - expr=parse_expr(self.query.breakdownFilter.breakdown), - ) - elif self.query.breakdownFilter.breakdown_type == "cohort": + + if self.query.breakdownFilter.breakdown_type == "cohort": if self.modifiers.inCohortVia == InCohortVia.leftjoin_conjoined: return ast.Alias( alias="breakdown_value", - expr=ast.Field(chain=["__in_cohort", "cohort_id"]), + expr=hogql_to_string(ast.Field(chain=["__in_cohort", "cohort_id"])), ) cohort_breakdown = ( @@ -90,19 +88,9 @@ def column_expr(self) -> ast.Expr: ) return ast.Alias( alias="breakdown_value", - expr=ast.Constant(value=cohort_breakdown), - ) - - if self.query.breakdownFilter.breakdown_type == "hogql": - return ast.Alias( - alias="breakdown_value", - expr=parse_expr(self.query.breakdownFilter.breakdown), + expr=hogql_to_string(ast.Constant(value=cohort_breakdown)), ) - # If there's no breakdown values - if len(self._breakdown_values) == 1 and self._breakdown_values[0] is None: - return ast.Alias(alias="breakdown_value", expr=ast.Field(chain=self._properties_chain)) - return ast.Alias(alias="breakdown_value", expr=self._get_breakdown_transform_func) def events_where_filter(self) -> ast.Expr | None: @@ -148,15 +136,14 @@ def events_where_filter(self) -> ast.Expr | None: else: left = ast.Field(chain=self._properties_chain) + if not self.is_histogram_breakdown: + left = hogql_to_string(left) + compare_ops = [] for _value in self._breakdown_values: - value: Optional[str | int | float] = _value + value: Optional[str] = str(_value) # non-cohorts are always strings # If the value is one of the "other" values, then use the `transform()` func - if ( - value == BREAKDOWN_OTHER_STRING_LABEL - or value == BREAKDOWN_OTHER_NUMERIC_LABEL - or value == float(BREAKDOWN_OTHER_NUMERIC_LABEL) - ): + if value == BREAKDOWN_OTHER_STRING_LABEL: transform_func = self._get_breakdown_transform_func compare_ops.append( ast.CompareOperation( @@ -164,11 +151,7 @@ def events_where_filter(self) -> ast.Expr | None: ) ) else: - if ( - value == BREAKDOWN_NULL_STRING_LABEL - or value == BREAKDOWN_NULL_NUMERIC_LABEL - or value == float(BREAKDOWN_NULL_NUMERIC_LABEL) - ): + if value == BREAKDOWN_NULL_STRING_LABEL: value = None compare_ops.append( @@ -184,30 +167,25 @@ def events_where_filter(self) -> ast.Expr | None: @cached_property def _get_breakdown_transform_func(self) -> ast.Call: - values = self._breakdown_values - all_values_are_ints_or_none = all(isinstance(value, int) or value is None for value in values) - all_values_are_floats_or_none = all(isinstance(value, float) or value is None for value in values) - - if all_values_are_ints_or_none: - breakdown_other_value = BREAKDOWN_OTHER_NUMERIC_LABEL - breakdown_null_value = BREAKDOWN_NULL_NUMERIC_LABEL - elif all_values_are_floats_or_none: - breakdown_other_value = float(BREAKDOWN_OTHER_NUMERIC_LABEL) - breakdown_null_value = float(BREAKDOWN_NULL_NUMERIC_LABEL) - else: - breakdown_other_value = BREAKDOWN_OTHER_STRING_LABEL - breakdown_null_value = BREAKDOWN_NULL_STRING_LABEL + if self.query.breakdownFilter.breakdown_type == "hogql": + return self._get_breakdown_values_transform(parse_expr(self.query.breakdownFilter.breakdown)) + return self._get_breakdown_values_transform(ast.Field(chain=self._properties_chain)) + def _get_breakdown_values_transform(self, node: ast.Expr) -> ast.Call: + breakdown_values = self._breakdown_values_ast return ast.Call( name="transform", args=[ ast.Call( name="ifNull", - args=[ast.Field(chain=self._properties_chain), ast.Constant(value=breakdown_null_value)], + args=[ + hogql_to_string(node), + ast.Constant(value=BREAKDOWN_NULL_STRING_LABEL), + ], ), - self._breakdown_values_ast, - self._breakdown_values_ast, - ast.Constant(value=breakdown_other_value), + breakdown_values, + breakdown_values, + ast.Constant(value=BREAKDOWN_OTHER_STRING_LABEL), ], ) @@ -220,15 +198,21 @@ def _breakdown_buckets_ast(self) -> ast.Array: return ast.Array(exprs=list(map(lambda v: ast.Constant(value=v), values))) - @cached_property + @property def _breakdown_values_ast(self) -> ast.Array: - return ast.Array(exprs=[ast.Constant(value=v) for v in self._breakdown_values]) + exprs: list[ast.Expr] = [] + for value in self._breakdown_values: + if isinstance(value, str): + exprs.append(ast.Constant(value=value)) + else: + exprs.append(hogql_to_string(ast.Constant(value=value))) + return ast.Array(exprs=exprs) @cached_property - def _all_breakdown_values(self) -> List[str | int | float | None]: + def _all_breakdown_values(self) -> List[str | int | None]: # Used in the actors query if self.breakdown_values_override is not None: - return cast(List[str | int | float | None], self.breakdown_values_override) + return cast(List[str | int | None], self.breakdown_values_override) if self.query.breakdownFilter is None: return [] @@ -243,25 +227,12 @@ def _all_breakdown_values(self) -> List[str | int | float | None]: query_date_range=self.query_date_range, modifiers=self.modifiers, ) - return cast(List[str | int | float | None], breakdown.get_breakdown_values()) + return cast(List[str | int | None], breakdown.get_breakdown_values()) @cached_property - def _breakdown_values(self) -> List[str | int | float]: - values = self._all_breakdown_values - if len(values) == 0 or all(value is None for value in values): - return [] - - if None in values: - all_values_are_ints_or_none = all(isinstance(value, int) or value is None for value in values) - all_values_are_floats_or_none = all(isinstance(value, float) or value is None for value in values) - - if all_values_are_ints_or_none: - values = [v if v is not None else BREAKDOWN_NULL_NUMERIC_LABEL for v in values] - elif all_values_are_floats_or_none: - values = [v if v is not None else float(BREAKDOWN_NULL_NUMERIC_LABEL) for v in values] - else: - values = [v if v is not None else BREAKDOWN_NULL_STRING_LABEL for v in values] - return cast(List[str | int | float], values) + def _breakdown_values(self) -> List[str | int]: + values = [BREAKDOWN_NULL_STRING_LABEL if v is None else v for v in self._all_breakdown_values] + return cast(List[str | int], values) @cached_property def has_breakdown_values(self) -> bool: diff --git a/posthog/hogql_queries/insights/trends/breakdown_values.py b/posthog/hogql_queries/insights/trends/breakdown_values.py index 7b1522d5f25c5..d9ab11891f210 100644 --- a/posthog/hogql_queries/insights/trends/breakdown_values.py +++ b/posthog/hogql_queries/insights/trends/breakdown_values.py @@ -97,6 +97,9 @@ def get_breakdown_values(self) -> List[str | int]: ), ) + if not self.histogram_bin_count: + select_field.expr = ast.Call(name="toString", args=[select_field.expr]) + if self.chart_display_type == ChartDisplayType.WorldMap: breakdown_limit = BREAKDOWN_VALUES_LIMIT_FOR_COUNTRIES else: @@ -211,23 +214,9 @@ def get_breakdown_values(self) -> List[str | int]: # Add "other" value if "other" is not hidden and we're not bucketing numeric values if self.hide_other_aggregation is not True and self.histogram_bin_count is None: - all_values_are_ints_or_none = all(isinstance(value, int) or value is None for value in values) - all_values_are_floats_or_none = all(isinstance(value, float) or value is None for value in values) - all_values_are_string_or_none = all(isinstance(value, str) or value is None for value in values) - - if all_values_are_string_or_none: - values = [BREAKDOWN_NULL_STRING_LABEL if value in (None, "") else value for value in values] - if needs_other: - values.insert(0, BREAKDOWN_OTHER_STRING_LABEL) - elif all_values_are_ints_or_none or all_values_are_floats_or_none: - if all_values_are_ints_or_none: - values = [BREAKDOWN_NULL_NUMERIC_LABEL if value is None else value for value in values] - if needs_other: - values.insert(0, BREAKDOWN_OTHER_NUMERIC_LABEL) - else: - values = [float(BREAKDOWN_NULL_NUMERIC_LABEL) if value is None else value for value in values] - if needs_other: - values.insert(0, float(BREAKDOWN_OTHER_NUMERIC_LABEL)) + values = [BREAKDOWN_NULL_STRING_LABEL if value in (None, "") else value for value in values] + if needs_other: + values = [BREAKDOWN_OTHER_STRING_LABEL] + values if len(values) == 0: values.insert(0, None) 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 f6eb3748afb2b..e2ec22fb9fb1c 100644 --- a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr +++ b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr @@ -187,7 +187,7 @@ # --- # name: TestTrends.test_breakdown_by_group_props_person_on_events ''' - SELECT e__group_0.properties___industry AS value, + SELECT toString(e__group_0.properties___industry) AS value, count(e.uuid) AS count FROM events AS e LEFT JOIN @@ -210,7 +210,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -231,7 +231,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(e__group_0.properties___industry, '$$_posthog_breakdown_null_$$'), ['finance', 'technology'], ['finance', 'technology'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__group_0.properties___industry), '$$_posthog_breakdown_null_$$'), ['finance', 'technology'], ['finance', 'technology'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), groups._timestamp) AS properties___industry, @@ -241,7 +241,7 @@ WHERE and(equals(groups.team_id, 2), ifNull(equals(index, 0), 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), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(e__group_0.properties___industry, 'finance'), 0), ifNull(equals(e__group_0.properties___industry, 'technology'), 0))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(toString(e__group_0.properties___industry), 'finance'), 0), ifNull(equals(toString(e__group_0.properties___industry), 'technology'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -287,7 +287,7 @@ # --- # name: TestTrends.test_breakdown_by_group_props_with_person_filter_person_on_events ''' - SELECT e__group_0.properties___industry AS value, + SELECT toString(e__group_0.properties___industry) AS value, count(e.uuid) AS count FROM events AS e LEFT JOIN @@ -310,7 +310,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -331,7 +331,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(e__group_0.properties___industry, '$$_posthog_breakdown_null_$$'), ['finance'], ['finance'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__group_0.properties___industry), '$$_posthog_breakdown_null_$$'), ['finance'], ['finance'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), groups._timestamp) AS properties___industry, @@ -341,7 +341,7 @@ WHERE and(equals(groups.team_id, 2), ifNull(equals(index, 0), 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), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, 'key'), ''), 'null'), '^"|"$', ''), 'value'), 0), ifNull(equals(e__group_0.properties___industry, 'finance'), 0)) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, 'key'), ''), 'null'), '^"|"$', ''), 'value'), 0), ifNull(equals(toString(e__group_0.properties___industry), 'finance'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -356,7 +356,7 @@ # --- # name: TestTrends.test_breakdown_filtering_with_properties_in_new_format ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC')))), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', ''), 'Firefox'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Windows'), 0)), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0))) @@ -371,7 +371,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -392,9 +392,9 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['second url'], ['second url'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['second url'], ['second url'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', ''), 'Firefox'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Windows'), 0)), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''), 'second url'), 0)) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', ''), 'Firefox'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Windows'), 0)), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')), 'second url'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -409,7 +409,7 @@ # --- # name: TestTrends.test_breakdown_filtering_with_properties_in_new_format.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC')))), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', ''), 'Firefox'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Windows'), 0)), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0))) @@ -423,24 +423,38 @@ # name: TestTrends.test_breakdown_filtering_with_properties_in_new_format.3 ''' SELECT groupArray(day_start) AS date, - groupArray(count) AS total + groupArray(count) AS total, + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, - day_start AS day_start + day_start AS day_start, + breakdown_value AS breakdown_value FROM (SELECT 0 AS total, - minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS day_start - FROM numbers(coalesce(dateDiff('day', assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), 0)) AS numbers - UNION ALL SELECT 0 AS total, - toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))) AS day_start + ticks.day_start AS day_start, + sec.breakdown_value AS breakdown_value + FROM + (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS day_start + FROM numbers(coalesce(dateDiff('day', assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), 0)) AS numbers + UNION ALL SELECT toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))) AS day_start) AS ticks + CROSS JOIN + (SELECT breakdown_value + FROM + (SELECT ['$$_posthog_breakdown_null_$$'] AS breakdown_value) ARRAY + JOIN breakdown_value AS breakdown_value) AS sec + ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start + toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$'], ['$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', ''), 'Firefox'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Windows'), 0)), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0)) - GROUP BY day_start) - GROUP BY day_start - ORDER BY day_start ASC) - ORDER BY sum(count) DESC + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$browser'), ''), 'null'), '^"|"$', ''), 'Firefox'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Windows'), 0)), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')))) + 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 sum(count) DESC, breakdown_value ASC LIMIT 10000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1 @@ -448,7 +462,7 @@ # --- # name: TestTrends.test_breakdown_weekly_active_users_aggregated ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')) AS value, count(DISTINCT e__pdi.person_id) AS count FROM events AS e INNER JOIN @@ -480,7 +494,7 @@ CROSS JOIN (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e__pdi.person_id AS actor_id, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['val', 'bor'], ['val', 'bor'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['val', 'bor'], ['val', 'bor'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -489,7 +503,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.distinct_id) - WHERE and(equals(e.team_id, 2), and(equals(e.event, '$pageview'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'bor'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')), toIntervalDay(7))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) + WHERE and(equals(e.team_id, 2), and(equals(e.event, '$pageview'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'val'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'bor'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')), toIntervalDay(7))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) GROUP BY timestamp, actor_id, breakdown_value) AS e WHERE and(ifNull(lessOrEquals(e.timestamp, plus(d.timestamp, toIntervalDay(1))), 0), ifNull(greater(e.timestamp, minus(d.timestamp, toIntervalDay(6))), 0)) @@ -506,7 +520,7 @@ # --- # name: TestTrends.test_breakdown_weekly_active_users_aggregated_materialized ''' - SELECT nullIf(nullIf(e.mat_key, ''), 'null') AS value, + SELECT toString(nullIf(nullIf(e.mat_key, ''), 'null')) AS value, count(DISTINCT e__pdi.person_id) AS count FROM events AS e INNER JOIN @@ -538,7 +552,7 @@ CROSS JOIN (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e__pdi.person_id AS actor_id, - transform(ifNull(nullIf(nullIf(e.mat_key, ''), 'null'), '$$_posthog_breakdown_null_$$'), ['val', 'bor'], ['val', 'bor'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(nullIf(nullIf(e.mat_key, ''), 'null')), '$$_posthog_breakdown_null_$$'), ['val', 'bor'], ['val', 'bor'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -547,7 +561,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.distinct_id) - WHERE and(equals(e.team_id, 2), and(equals(e.event, '$pageview'), or(ifNull(equals(nullIf(nullIf(e.mat_key, ''), 'null'), 'val'), 0), ifNull(equals(nullIf(nullIf(e.mat_key, ''), 'null'), 'bor'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')), toIntervalDay(7))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) + WHERE and(equals(e.team_id, 2), and(equals(e.event, '$pageview'), or(ifNull(equals(toString(nullIf(nullIf(e.mat_key, ''), 'null')), 'val'), 0), ifNull(equals(toString(nullIf(nullIf(e.mat_key, ''), 'null')), 'bor'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')), toIntervalDay(7))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) GROUP BY timestamp, actor_id, breakdown_value) AS e WHERE and(ifNull(lessOrEquals(e.timestamp, plus(d.timestamp, toIntervalDay(1))), 0), ifNull(greater(e.timestamp, minus(d.timestamp, toIntervalDay(6))), 0)) @@ -584,7 +598,7 @@ # --- # name: TestTrends.test_breakdown_weekly_active_users_daily_based_on_action.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')) AS value, count(DISTINCT e__pdi.person_id) AS count FROM events AS e INNER JOIN @@ -622,7 +636,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -654,7 +668,7 @@ CROSS JOIN (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e__pdi.person_id AS actor_id, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['val'], ['val'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['val'], ['val'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -679,7 +693,7 @@ FROM cohortpeople WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2)) GROUP BY cohortpeople.person_id, cohortpeople.cohort_id, cohortpeople.version - HAVING ifNull(greater(sum(cohortpeople.sign), 0), 0))), 0))), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')), toIntervalDay(7))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), 0)) + HAVING ifNull(greater(sum(cohortpeople.sign), 0), 0))), 0))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'val'), 0)), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')), toIntervalDay(7))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), 0)) GROUP BY timestamp, actor_id, breakdown_value) AS e WHERE and(ifNull(lessOrEquals(e.timestamp, plus(d.timestamp, toIntervalDay(1))), 0), ifNull(greater(e.timestamp, minus(d.timestamp, toIntervalDay(6))), 0)) @@ -699,7 +713,7 @@ # --- # name: TestTrends.test_breakdown_with_filter_groups_person_on_events ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e LEFT JOIN @@ -722,7 +736,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -743,7 +757,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['uh', 'oh'], ['uh', 'oh'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['uh', 'oh'], ['uh', 'oh'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), groups._timestamp) AS properties___industry, @@ -753,7 +767,7 @@ WHERE and(equals(groups.team_id, 2), ifNull(equals(index, 0), 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), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(e__group_0.properties___industry, 'finance'), 0), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'uh'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'oh'), 0))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(e__group_0.properties___industry, 'finance'), 0), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'uh'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'oh'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -782,7 +796,7 @@ # --- # name: TestTrends.test_breakdown_with_filter_groups_person_on_events_v2.1 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e LEFT JOIN @@ -805,7 +819,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -826,7 +840,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT ifNull(nullIf(e__override.override_person_id, '00000000-0000-0000-0000-000000000000'), e.person_id)) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['uh', 'oh'], ['uh', 'oh'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['uh', 'oh'], ['uh', 'oh'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT OUTER JOIN (SELECT argMax(person_overrides.override_person_id, person_overrides.version) AS override_person_id, @@ -842,7 +856,7 @@ WHERE and(equals(groups.team_id, 2), ifNull(equals(index, 0), 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), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(e__group_0.properties___industry, 'finance'), 0), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'uh'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'oh'), 0))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(e__group_0.properties___industry, 'finance'), 0), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'uh'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), 'oh'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -857,7 +871,7 @@ # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(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')))), and(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'))) @@ -872,7 +886,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -893,7 +907,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e__pdi.person_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['other_value', '$$_posthog_breakdown_null_$$', 'value'], ['other_value', '$$_posthog_breakdown_null_$$', 'value'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['other_value', '$$_posthog_breakdown_null_$$', 'value'], ['other_value', '$$_posthog_breakdown_null_$$', 'value'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1.0 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -902,7 +916,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.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'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'other_value'), 0), isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value'), 0))) + 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'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'other_value'), 0), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -917,7 +931,7 @@ # --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(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')))), and(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'))) @@ -932,7 +946,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -953,7 +967,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e__pdi.person_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['other_value', '$$_posthog_breakdown_null_$$', 'value'], ['other_value', '$$_posthog_breakdown_null_$$', 'value'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['other_value', '$$_posthog_breakdown_null_$$', 'value'], ['other_value', '$$_posthog_breakdown_null_$$', 'value'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1.0 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -962,7 +976,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.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'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'other_value'), 0), isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value'), 0))) + 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'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'other_value'), 0), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -1242,7 +1256,7 @@ # --- # name: TestTrends.test_mau_with_breakdown_filtering_and_prop_filter ''' - SELECT e__pdi__person.`properties___$some_prop` AS value, + SELECT toString(e__pdi__person.`properties___$some_prop`) AS value, count(DISTINCT e__pdi.person_id) AS count FROM events AS e INNER JOIN @@ -1276,7 +1290,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -1308,7 +1322,7 @@ CROSS JOIN (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, e__pdi.person_id AS actor_id, - transform(ifNull(e__pdi__person.`properties___$some_prop`, '$$_posthog_breakdown_null_$$'), ['some_val2', 'some_val'], ['some_val2', 'some_val'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__pdi__person.`properties___$some_prop`), '$$_posthog_breakdown_null_$$'), ['some_val2', 'some_val'], ['some_val2', 'some_val'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -1329,7 +1343,7 @@ WHERE equals(person.team_id, 2) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__pdi__person ON equals(e__pdi.e__pdi___person_id, e__pdi__person.id) - WHERE and(equals(e.team_id, 2), and(equals(e.event, 'sign up'), ifNull(equals(e__pdi__person.properties___filter_prop, 'filter_val'), 0), or(ifNull(equals(e__pdi__person.`properties___$some_prop`, 'some_val2'), 0), ifNull(equals(e__pdi__person.`properties___$some_prop`, 'some_val'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), toIntervalDay(30))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) + WHERE and(equals(e.team_id, 2), and(equals(e.event, 'sign up'), ifNull(equals(e__pdi__person.properties___filter_prop, 'filter_val'), 0), or(ifNull(equals(toString(e__pdi__person.`properties___$some_prop`), 'some_val2'), 0), ifNull(equals(toString(e__pdi__person.`properties___$some_prop`), 'some_val'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), toIntervalDay(30))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) GROUP BY timestamp, actor_id, breakdown_value) AS e WHERE and(ifNull(lessOrEquals(e.timestamp, plus(d.timestamp, toIntervalDay(1))), 0), ifNull(greater(e.timestamp, minus(d.timestamp, toIntervalDay(29))), 0)) @@ -1349,7 +1363,7 @@ # --- # name: TestTrends.test_mau_with_breakdown_filtering_and_prop_filter_poe_v2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', '')) AS value, count(DISTINCT ifNull(nullIf(e__override.override_person_id, '00000000-0000-0000-0000-000000000000'), e.person_id)) AS count FROM events AS e LEFT OUTER JOIN @@ -1370,7 +1384,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -1402,7 +1416,7 @@ CROSS JOIN (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, ifNull(nullIf(e__override.override_person_id, '00000000-0000-0000-0000-000000000000'), e.person_id) AS actor_id, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['some_val2', 'some_val'], ['some_val2', 'some_val'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['some_val2', 'some_val'], ['some_val2', 'some_val'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT OUTER JOIN (SELECT argMax(person_overrides.override_person_id, person_overrides.version) AS override_person_id, @@ -1410,7 +1424,7 @@ FROM person_overrides WHERE equals(person_overrides.team_id, 2) GROUP BY person_overrides.old_person_id) AS e__override ON equals(e.person_id, e__override.old_person_id) - WHERE and(equals(e.team_id, 2), and(equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, 'filter_prop'), ''), 'null'), '^"|"$', ''), 'filter_val'), 0), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', ''), 'some_val2'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', ''), 'some_val'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), toIntervalDay(30))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) + WHERE and(equals(e.team_id, 2), and(equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, 'filter_prop'), ''), 'null'), '^"|"$', ''), 'filter_val'), 0), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', '')), 'some_val2'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.person_properties, '$some_prop'), ''), 'null'), '^"|"$', '')), 'some_val'), 0))), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), toIntervalDay(30))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) GROUP BY timestamp, actor_id, breakdown_value) AS e WHERE and(ifNull(lessOrEquals(e.timestamp, plus(d.timestamp, toIntervalDay(1))), 0), ifNull(greater(e.timestamp, minus(d.timestamp, toIntervalDay(29))), 0)) @@ -1476,7 +1490,7 @@ # --- # name: TestTrends.test_person_filtering_in_cohort_in_action.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e INNER JOIN @@ -1503,7 +1517,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -1524,7 +1538,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -1538,7 +1552,7 @@ FROM cohortpeople WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2)) GROUP BY cohortpeople.person_id, cohortpeople.cohort_id, cohortpeople.version - HAVING ifNull(greater(sum(cohortpeople.sign), 0), 0))), 0)), or(isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'other_value'), 0))) + HAVING ifNull(greater(sum(cohortpeople.sign), 0), 0))), 0)), or(isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'other_value'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -1573,7 +1587,7 @@ # --- # name: TestTrends.test_person_filtering_in_cohort_in_action_poe_v2.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e LEFT OUTER JOIN @@ -1599,7 +1613,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -1620,7 +1634,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT OUTER JOIN (SELECT argMax(person_overrides.override_person_id, person_overrides.version) AS override_person_id, @@ -1633,7 +1647,7 @@ FROM cohortpeople WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2)) GROUP BY cohortpeople.person_id, cohortpeople.cohort_id, cohortpeople.version - HAVING ifNull(greater(sum(cohortpeople.sign), 0), 0))), 0)), or(isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'other_value'), 0))) + HAVING ifNull(greater(sum(cohortpeople.sign), 0), 0))), 0)), or(isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'other_value'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -2217,7 +2231,7 @@ # --- # name: TestTrends.test_timezones_daily.4 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC')))), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'))) @@ -2232,7 +2246,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -2253,7 +2267,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e__pdi.person_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['Mac'], ['Mac'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['Mac'], ['Mac'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -2262,7 +2276,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.distinct_id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0)) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')), 'Mac'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -2408,7 +2422,7 @@ # --- # name: TestTrends.test_timezones_daily_minus_utc.4 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix')))), lessOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix')))), and(greaterOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix')))), lessOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix'))), equals(e.event, 'sign up'))) @@ -2423,7 +2437,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -2444,7 +2458,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e__pdi.person_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'America/Phoenix')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['Mac'], ['Mac'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['Mac'], ['Mac'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -2453,7 +2467,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.distinct_id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix')))), lessOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix'))), equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0)) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix')))), lessOrEquals(toTimeZone(e.timestamp, 'America/Phoenix'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix'))), equals(e.event, 'sign up'), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')), 'Mac'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -2599,7 +2613,7 @@ # --- # name: TestTrends.test_timezones_daily_plus_utc.4 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo')))), lessOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo')))), and(greaterOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo')))), lessOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo'))), equals(e.event, 'sign up'))) @@ -2614,7 +2628,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -2635,7 +2649,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e__pdi.person_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'Asia/Tokyo')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['Mac'], ['Mac'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['Mac'], ['Mac'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -2644,7 +2658,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.distinct_id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo')))), lessOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo'))), equals(e.event, 'sign up'), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', ''), 'Mac'), 0)) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo')))), lessOrEquals(toTimeZone(e.timestamp, 'Asia/Tokyo'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo'))), equals(e.event, 'sign up'), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$os'), ''), 'null'), '^"|"$', '')), 'Mac'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -2992,7 +3006,7 @@ # --- # name: TestTrends.test_trend_breakdown_user_props_with_filter_with_partial_property_pushdowns ''' - SELECT e__pdi__person.properties___email AS value, + SELECT toString(e__pdi__person.properties___email) AS value, count(e.uuid) AS count FROM events AS e INNER JOIN @@ -3027,7 +3041,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -3048,7 +3062,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(e__pdi__person.properties___email, '$$_posthog_breakdown_null_$$'), ['test2@posthog.com', 'test@gmail.com', 'test5@posthog.com', 'test4@posthog.com', 'test3@posthog.com'], ['test2@posthog.com', 'test@gmail.com', 'test5@posthog.com', 'test4@posthog.com', 'test3@posthog.com'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__pdi__person.properties___email), '$$_posthog_breakdown_null_$$'), ['test2@posthog.com', 'test@gmail.com', 'test5@posthog.com', 'test4@posthog.com', 'test3@posthog.com'], ['test2@posthog.com', 'test@gmail.com', 'test5@posthog.com', 'test4@posthog.com', 'test3@posthog.com'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, @@ -3070,7 +3084,7 @@ WHERE equals(person.team_id, 2) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__pdi__person ON equals(e__pdi.e__pdi___person_id, e__pdi__person.id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(or(ifNull(notILike(e__pdi__person.properties___email, '%@posthog.com%'), 1), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), or(ifNull(equals(e__pdi__person.`properties___$os`, 'android'), 0), ifNull(equals(e__pdi__person.`properties___$browser`, 'safari'), 0))), or(ifNull(equals(e__pdi__person.properties___email, 'test2@posthog.com'), 0), ifNull(equals(e__pdi__person.properties___email, 'test@gmail.com'), 0), ifNull(equals(e__pdi__person.properties___email, 'test5@posthog.com'), 0), ifNull(equals(e__pdi__person.properties___email, 'test4@posthog.com'), 0), ifNull(equals(e__pdi__person.properties___email, 'test3@posthog.com'), 0))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(or(ifNull(notILike(e__pdi__person.properties___email, '%@posthog.com%'), 1), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0)), or(ifNull(equals(e__pdi__person.`properties___$os`, 'android'), 0), ifNull(equals(e__pdi__person.`properties___$browser`, 'safari'), 0))), or(ifNull(equals(toString(e__pdi__person.properties___email), 'test2@posthog.com'), 0), ifNull(equals(toString(e__pdi__person.properties___email), 'test@gmail.com'), 0), ifNull(equals(toString(e__pdi__person.properties___email), 'test5@posthog.com'), 0), ifNull(equals(toString(e__pdi__person.properties___email), 'test4@posthog.com'), 0), ifNull(equals(toString(e__pdi__person.properties___email), 'test3@posthog.com'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -3085,7 +3099,7 @@ # --- # name: TestTrends.test_trend_breakdown_user_props_with_filter_with_partial_property_pushdowns.2 ''' - SELECT e__pdi__person.properties___email AS value, + SELECT toString(e__pdi__person.properties___email) AS value, count(e.uuid) AS count FROM events AS e INNER JOIN @@ -3120,7 +3134,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -3141,7 +3155,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.uuid) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(e__pdi__person.properties___email, '$$_posthog_breakdown_null_$$'), ['test2@posthog.com'], ['test2@posthog.com'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__pdi__person.properties___email), '$$_posthog_breakdown_null_$$'), ['test2@posthog.com'], ['test2@posthog.com'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, @@ -3163,7 +3177,7 @@ WHERE equals(person.team_id, 2) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__pdi__person ON equals(e__pdi.e__pdi___person_id, e__pdi__person.id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(ifNull(equals(e__pdi__person.`properties___$os`, 'android'), 0), ifNull(equals(e__pdi__person.`properties___$browser`, 'chrome'), 0)), and(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0), ifNull(ilike(e__pdi__person.properties___email, '%@posthog.com%'), 0)), ifNull(equals(e__pdi__person.properties___email, 'test2@posthog.com'), 0)) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), and(ifNull(equals(e__pdi__person.`properties___$os`, 'android'), 0), ifNull(equals(e__pdi__person.`properties___$browser`, 'chrome'), 0)), and(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', ''), 'val'), 0), ifNull(ilike(e__pdi__person.properties___email, '%@posthog.com%'), 0)), ifNull(equals(toString(e__pdi__person.properties___email), 'test2@posthog.com'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -3248,7 +3262,7 @@ # --- # name: TestTrends.test_trends_aggregate_by_distinct_id.2 ''' - SELECT e__pdi__person.`properties___$some_prop` AS value, + SELECT toString(e__pdi__person.`properties___$some_prop`) AS value, count(e.uuid) AS count FROM events AS e INNER JOIN @@ -3281,7 +3295,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -3302,7 +3316,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e.distinct_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(e__pdi__person.`properties___$some_prop`, '$$_posthog_breakdown_null_$$'), ['some_val', '$$_posthog_breakdown_null_$$'], ['some_val', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__pdi__person.`properties___$some_prop`), '$$_posthog_breakdown_null_$$'), ['some_val', '$$_posthog_breakdown_null_$$'], ['some_val', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, @@ -3322,7 +3336,7 @@ WHERE equals(person.team_id, 2) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__pdi__person ON equals(e__pdi.e__pdi___person_id, e__pdi__person.id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(e__pdi__person.`properties___$some_prop`, 'some_val'), 0), isNull(e__pdi__person.`properties___$some_prop`))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(toString(e__pdi__person.`properties___$some_prop`), 'some_val'), 0), isNull(toString(e__pdi__person.`properties___$some_prop`)))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -3415,7 +3429,7 @@ # --- # name: TestTrends.test_trends_aggregate_by_distinct_id.6 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_prop'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_prop'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC')))), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'))) @@ -3430,7 +3444,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -3451,9 +3465,9 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e.distinct_id) AS total, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_prop'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$'], ['$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_prop'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$'], ['$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_prop'), ''), 'null'), '^"|"$', ''))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_prop'), ''), 'null'), '^"|"$', '')))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -3520,7 +3534,7 @@ # --- # name: TestTrends.test_trends_breakdown_cumulative ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(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')))), and(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'))) @@ -3535,7 +3549,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT day_start AS day_start, sum(count) OVER (PARTITION BY breakdown_value @@ -3561,7 +3575,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT e__pdi.person_id) AS total, min(toStartOfDay(toTimeZone(e.timestamp, 'UTC'))) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -3570,7 +3584,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.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'), or(isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'other_value'), 0))) + 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'), or(isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'other_value'), 0))) GROUP BY e__pdi.person_id, breakdown_value) GROUP BY day_start, @@ -3585,7 +3599,7 @@ # --- # name: TestTrends.test_trends_breakdown_cumulative_poe_v2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(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')))), and(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'))) @@ -3600,7 +3614,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT day_start AS day_start, sum(count) OVER (PARTITION BY breakdown_value @@ -3626,7 +3640,7 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(DISTINCT ifNull(nullIf(e__override.override_person_id, '00000000-0000-0000-0000-000000000000'), e.person_id)) AS total, min(toStartOfDay(toTimeZone(e.timestamp, 'UTC'))) AS day_start, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], ['$$_posthog_breakdown_null_$$', 'value', 'other_value'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 LEFT OUTER JOIN (SELECT argMax(person_overrides.override_person_id, person_overrides.version) AS override_person_id, @@ -3634,7 +3648,7 @@ FROM person_overrides WHERE equals(person_overrides.team_id, 2) GROUP BY person_overrides.old_person_id) AS e__override ON equals(e.person_id, e__override.old_person_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'), or(isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'other_value'), 0))) + 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'), or(isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'other_value'), 0))) GROUP BY ifNull(nullIf(e__override.override_person_id, '00000000-0000-0000-0000-000000000000'), e.person_id), breakdown_value) GROUP BY day_start, @@ -3649,7 +3663,7 @@ # --- # name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, max(e__session.duration) AS count FROM events AS e INNER JOIN @@ -3672,7 +3686,7 @@ breakdown_value AS breakdown_value FROM (SELECT any(e__session.duration) AS session_duration, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['value2', 'value1', '$$_posthog_breakdown_null_$$'], ['value2', 'value1', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['value2', 'value1', '$$_posthog_breakdown_null_$$'], ['value2', 'value1', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT events.`$session_id` AS id, @@ -3680,7 +3694,7 @@ FROM events WHERE and(equals(events.team_id, 2), greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), ifNull(notEquals(id, ''), 1)) GROUP BY id) AS e__session ON equals(e.`$session_id`, e__session.id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value2'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value1'), 0), isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value2'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value1'), 0), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))))) GROUP BY e__session.id, breakdown_value) GROUP BY breakdown_value @@ -3691,7 +3705,7 @@ # --- # name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, max(e__session.duration) AS count FROM events AS e INNER JOIN @@ -3714,7 +3728,7 @@ breakdown_value AS breakdown_value FROM (SELECT any(e__session.duration) AS session_duration, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['value2', 'value1', '$$_posthog_breakdown_null_$$'], ['value2', 'value1', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['value2', 'value1', '$$_posthog_breakdown_null_$$'], ['value2', 'value1', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT events.`$session_id` AS id, @@ -3722,7 +3736,7 @@ FROM events WHERE and(equals(events.team_id, 2), greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), ifNull(notEquals(id, ''), 1)) GROUP BY id) AS e__session ON equals(e.`$session_id`, e__session.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'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value2'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value1'), 0), isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')))) + 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'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value2'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value1'), 0), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''))))) GROUP BY e__session.id, breakdown_value) GROUP BY breakdown_value @@ -3854,7 +3868,7 @@ # --- # name: TestTrends.test_trends_count_per_user_average_aggregated_with_event_property_breakdown_with_sampling ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')) AS value, count(e.uuid) AS count FROM events AS e WHERE and(equals(e.team_id, 2), and(greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-07 23:59:59', 6, 'UTC')))), equals(e.event, 'viewed video')) @@ -3874,7 +3888,7 @@ breakdown_value AS breakdown_value FROM (SELECT count(e.uuid) AS total, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['red', 'blue', '$$_posthog_breakdown_null_$$'], ['red', 'blue', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['red', 'blue', '$$_posthog_breakdown_null_$$'], ['red', 'blue', '$$_posthog_breakdown_null_$$'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1.0 INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, @@ -3883,7 +3897,7 @@ WHERE equals(person_distinct_id2.team_id, 2) GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS e__pdi ON equals(e.distinct_id, e__pdi.distinct_id) - WHERE and(equals(e.team_id, 2), and(equals(e.event, 'viewed video'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', ''), 'red'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', ''), 'blue'), 0), isNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')))), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')), toIntervalDay(0))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-07 23:59:59', 6, 'UTC')))) + WHERE and(equals(e.team_id, 2), and(equals(e.event, 'viewed video'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')), 'red'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')), 'blue'), 0), isNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', ''))))), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')), toIntervalDay(0))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-07 23:59:59', 6, 'UTC')))) GROUP BY e__pdi.person_id, breakdown_value) GROUP BY breakdown_value) @@ -4098,7 +4112,7 @@ # --- # name: TestTrends.test_trends_person_breakdown_with_session_property_single_aggregate_math_and_breakdown ''' - SELECT e__pdi__person.`properties___$some_prop` AS value, + SELECT toString(e__pdi__person.`properties___$some_prop`) AS value, max(e__session.duration) AS count FROM events AS e INNER JOIN @@ -4139,7 +4153,7 @@ breakdown_value AS breakdown_value FROM (SELECT any(e__session.duration) AS session_duration, - transform(ifNull(e__pdi__person.`properties___$some_prop`, '$$_posthog_breakdown_null_$$'), ['some_val', 'another_val'], ['some_val', 'another_val'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e__pdi__person.`properties___$some_prop`), '$$_posthog_breakdown_null_$$'), ['some_val', 'another_val'], ['some_val', 'another_val'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM events AS e SAMPLE 1 INNER JOIN (SELECT events.`$session_id` AS id, @@ -4165,7 +4179,7 @@ WHERE equals(person.team_id, 2) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) SETTINGS optimize_aggregation_in_order=1) AS e__pdi__person ON equals(e__pdi.e__pdi___person_id, e__pdi__person.id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(e__pdi__person.`properties___$some_prop`, 'some_val'), 0), ifNull(equals(e__pdi__person.`properties___$some_prop`, 'another_val'), 0))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(toString(e__pdi__person.`properties___$some_prop`), 'some_val'), 0), ifNull(equals(toString(e__pdi__person.`properties___$some_prop`), 'another_val'), 0))) GROUP BY e__session.id, breakdown_value) GROUP BY breakdown_value @@ -4316,7 +4330,7 @@ # --- # name: TestTrends.test_trends_with_session_property_total_volume_math_with_breakdowns ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, max(e__session.duration) AS count FROM events AS e INNER JOIN @@ -4337,7 +4351,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -4361,7 +4375,7 @@ breakdown_value AS breakdown_value FROM (SELECT any(e__session.duration) AS session_duration, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['value2', 'value1'], ['value2', 'value1'], '$$_posthog_breakdown_other_$$') AS breakdown_value, + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['value2', 'value1'], ['value2', 'value1'], '$$_posthog_breakdown_other_$$') AS breakdown_value, toStartOfWeek(toTimeZone(e.timestamp, 'UTC'), 0) AS day_start FROM events AS e SAMPLE 1 INNER JOIN @@ -4370,7 +4384,7 @@ FROM events WHERE and(equals(events.team_id, 2), greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), ifNull(notEquals(id, ''), 1)) GROUP BY id) AS e__session ON equals(e.`$session_id`, e__session.id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value2'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value1'), 0))) + WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value2'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value1'), 0))) GROUP BY day_start, e__session.id, breakdown_value, @@ -4389,7 +4403,7 @@ # --- # name: TestTrends.test_trends_with_session_property_total_volume_math_with_breakdowns.2 ''' - SELECT replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '') AS value, + SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, max(e__session.duration) AS count FROM events AS e INNER JOIN @@ -4410,7 +4424,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -4434,7 +4448,7 @@ breakdown_value AS breakdown_value FROM (SELECT any(e__session.duration) AS session_duration, - transform(ifNull(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), '$$_posthog_breakdown_null_$$'), ['value2', 'value1'], ['value2', 'value1'], '$$_posthog_breakdown_other_$$') AS breakdown_value, + transform(ifNull(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), '$$_posthog_breakdown_null_$$'), ['value2', 'value1'], ['value2', 'value1'], '$$_posthog_breakdown_other_$$') AS breakdown_value, toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start FROM events AS e SAMPLE 1 INNER JOIN @@ -4443,7 +4457,7 @@ FROM events WHERE and(equals(events.team_id, 2), greaterOrEquals(toTimeZone(events.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(events.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), ifNull(notEquals(id, ''), 1)) GROUP BY id) AS e__session ON equals(e.`$session_id`, e__session.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'), or(ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value2'), 0), ifNull(equals(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', ''), 'value1'), 0))) + 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'), or(ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value2'), 0), ifNull(equals(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), 'value1'), 0))) GROUP BY day_start, e__session.id, breakdown_value, diff --git a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends_data_warehouse_query.ambr b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends_data_warehouse_query.ambr index db9e8e1d45000..1e3bc1b5cbad6 100644 --- a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends_data_warehouse_query.ambr +++ b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends_data_warehouse_query.ambr @@ -1,7 +1,7 @@ # serializer version: 1 # name: TestTrendsDataWarehouseQuery.test_trends_breakdown ''' - SELECT e.prop_1 AS value, + SELECT toString(e.prop_1) AS value, count(e.id) AS count FROM s3('http://host.docker.internal:19000/posthog/test_storage_bucket-posthog.hogql.datawarehouse.trendquery/*.parquet', 'object_storage_root_user', 'object_storage_root_password', 'Parquet', 'id String, prop_1 String, prop_2 String, created DateTime64(3, \'UTC\')') AS e WHERE and(and(ifNull(greaterOrEquals(toTimeZone(e.created, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toTimeZone(e.created, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0)), and(ifNull(greaterOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0))) @@ -16,7 +16,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -37,9 +37,9 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.id) AS total, toStartOfDay(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC')) AS day_start, - transform(ifNull(e.prop_1, '$$_posthog_breakdown_null_$$'), ['d', 'c', 'b', 'a'], ['d', 'c', 'b', 'a'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e.prop_1), '$$_posthog_breakdown_null_$$'), ['d', 'c', 'b', 'a'], ['d', 'c', 'b', 'a'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM s3('http://host.docker.internal:19000/posthog/test_storage_bucket-posthog.hogql.datawarehouse.trendquery/*.parquet', 'object_storage_root_user', 'object_storage_root_password', 'Parquet', 'id String, prop_1 String, prop_2 String, created DateTime64(3, \'UTC\')') AS e - WHERE and(ifNull(greaterOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0), or(equals(e.prop_1, 'd'), equals(e.prop_1, 'c'), equals(e.prop_1, 'b'), equals(e.prop_1, 'a'))) + WHERE and(ifNull(greaterOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0), or(ifNull(equals(toString(e.prop_1), 'd'), 0), ifNull(equals(toString(e.prop_1), 'c'), 0), ifNull(equals(toString(e.prop_1), 'b'), 0), ifNull(equals(toString(e.prop_1), 'a'), 0))) GROUP BY day_start, breakdown_value) GROUP BY day_start, @@ -54,7 +54,7 @@ # --- # name: TestTrendsDataWarehouseQuery.test_trends_breakdown_with_property ''' - SELECT e.prop_1 AS value, + SELECT toString(e.prop_1) AS value, count(e.id) AS count FROM s3('http://host.docker.internal:19000/posthog/test_storage_bucket-posthog.hogql.datawarehouse.trendquery/*.parquet', 'object_storage_root_user', 'object_storage_root_password', 'Parquet', 'id String, prop_1 String, prop_2 String, created DateTime64(3, \'UTC\')') AS e WHERE and(and(ifNull(greaterOrEquals(toTimeZone(e.created, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toTimeZone(e.created, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0)), and(ifNull(greaterOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0), equals(e.prop_1, 'a'))) @@ -69,7 +69,7 @@ ''' SELECT groupArray(day_start) AS date, groupArray(count) AS total, - ifNull(toString(breakdown_value), '') AS breakdown_value + ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM (SELECT sum(total) AS count, day_start AS day_start, @@ -90,9 +90,9 @@ ORDER BY sec.breakdown_value ASC, day_start ASC UNION ALL SELECT count(e.id) AS total, toStartOfDay(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC')) AS day_start, - transform(ifNull(e.prop_1, '$$_posthog_breakdown_null_$$'), ['a'], ['a'], '$$_posthog_breakdown_other_$$') AS breakdown_value + transform(ifNull(toString(e.prop_1), '$$_posthog_breakdown_null_$$'), ['a'], ['a'], '$$_posthog_breakdown_other_$$') AS breakdown_value FROM s3('http://host.docker.internal:19000/posthog/test_storage_bucket-posthog.hogql.datawarehouse.trendquery/*.parquet', 'object_storage_root_user', 'object_storage_root_password', 'Parquet', 'id String, prop_1 String, prop_2 String, created DateTime64(3, \'UTC\')') AS e - WHERE and(ifNull(greaterOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0), equals(e.prop_1, 'a'), equals(e.prop_1, 'a')) + WHERE and(ifNull(greaterOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(toDateTime(toTimeZone(e.created, 'UTC'), 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))), 0), equals(e.prop_1, 'a'), ifNull(equals(toString(e.prop_1), 'a'), 0)) GROUP BY day_start, breakdown_value) GROUP BY day_start, diff --git a/posthog/hogql_queries/insights/trends/test/test_trends.py b/posthog/hogql_queries/insights/trends/test/test_trends.py index 1ac54e16de629..9e885fbadcc1d 100644 --- a/posthog/hogql_queries/insights/trends/test/test_trends.py +++ b/posthog/hogql_queries/insights/trends/test/test_trends.py @@ -5180,7 +5180,9 @@ def test_breakdown_filtering_with_properties_in_new_format(self): ) response = sorted(response, key=lambda x: x["label"]) - self.assertEqual(len(response), 0) + self.assertEqual(len(response), 1) + self.assertEqual(response[0]["label"], "$$_posthog_breakdown_null_$$") + self.assertEqual(response[0]["count"], 0) @also_test_with_person_on_events_v2 @snapshot_clickhouse_queries diff --git a/posthog/hogql_queries/insights/trends/test/test_trends_query_runner.py b/posthog/hogql_queries/insights/trends/test/test_trends_query_runner.py index 433df7c7df23b..8d14950ec23b2 100644 --- a/posthog/hogql_queries/insights/trends/test/test_trends_query_runner.py +++ b/posthog/hogql_queries/insights/trends/test/test_trends_query_runner.py @@ -381,7 +381,7 @@ def test_trends_query_formula_breakdown_no_data(self): TrendsFilter(formula="A+B"), BreakdownFilter(breakdown_type=BreakdownType.person, breakdown="$browser"), ) - self.assertEqual([], response.results) + self.assertEqual([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], response.results[0]["data"]) def test_trends_query_formula_aggregate(self): self._create_test_events() @@ -714,16 +714,7 @@ def test_trends_breakdowns_multiple_hogql(self): breakdown_labels = [result["breakdown_value"] for result in response.results] assert len(response.results) == 8 - assert breakdown_labels == [ - "Chrome", - "Firefox", - "Edge", - "Safari", - "Chrome", - "Edge", - "Firefox", - "Safari", - ] + assert breakdown_labels == ["Chrome", "Firefox", "Edge", "Safari", "Chrome", "Edge", "Firefox", "Safari"] assert response.results[0]["label"] == f"$pageview - Chrome" assert response.results[1]["label"] == f"$pageview - Firefox" assert response.results[2]["label"] == f"$pageview - Edge" @@ -823,6 +814,7 @@ def test_trends_breakdown_and_aggregation_query_orchestration(self): 10, 0, ] + assert response.results[1]["data"] == [ 20, 0, @@ -1606,9 +1598,8 @@ def test_to_actors_query_options_breakdowns_boolean(self): assert response.series == [InsightActorsQuerySeries(label="$pageview", value=0)] assert response.breakdown == [ - # BreakdownItem(label="Other", value="$$_posthog_breakdown_other_$$"), # TODO: Add when "Other" works - BreakdownItem(label="true", value=1), - BreakdownItem(label="false", value=0), + BreakdownItem(label="true", value="true"), + BreakdownItem(label="false", value="false"), ] def test_to_actors_query_options_breakdowns_histogram(self): diff --git a/posthog/hogql_queries/insights/trends/trends_query_builder.py b/posthog/hogql_queries/insights/trends/trends_query_builder.py index 7be735d3b0a8b..a911e4bf8302a 100644 --- a/posthog/hogql_queries/insights/trends/trends_query_builder.py +++ b/posthog/hogql_queries/insights/trends/trends_query_builder.py @@ -14,6 +14,7 @@ from posthog.models.action.action import Action from posthog.models.filters.mixins.utils import cached_property from posthog.models.team.team import Team +from posthog.queries.trends.breakdown import BREAKDOWN_NULL_STRING_LABEL from posthog.schema import ( ActionsNode, DataWarehouseNode, @@ -68,7 +69,7 @@ def build_query(self) -> ast.SelectQuery | ast.SelectUnionQuery: return full_query def build_actors_query( - self, time_frame: Optional[str] = None, breakdown_filter: Optional[str | int] = None + self, time_frame: Optional[str] = None, breakdown_filter: Optional[str] = None ) -> ast.SelectQuery | ast.SelectUnionQuery: breakdown = self._breakdown(is_actors_query=True, breakdown_values_override=breakdown_filter) @@ -292,7 +293,8 @@ def _get_events_subquery( # Just breakdowns elif breakdown.enabled: if not is_actors_query: - default_query.select.append(breakdown.column_expr()) + breakdown_expr = breakdown.column_expr() + default_query.select.append(breakdown_expr) default_query.group_by.append(ast.Field(chain=["breakdown_value"])) # Just session duration math property elif self._aggregation_operation.aggregating_on_session_duration(): @@ -369,7 +371,7 @@ def _outer_select_query(self, breakdown: Breakdown, inner_query: ast.SelectQuery name="ifNull", args=[ ast.Call(name="toString", args=[ast.Field(chain=["breakdown_value"])]), - ast.Constant(value=""), + ast.Constant(value=BREAKDOWN_NULL_STRING_LABEL), ], ), ) @@ -565,7 +567,7 @@ def session_duration_math_property_wrapper(self, default_query: ast.SelectQuery) query.group_by = [] return query - def _breakdown(self, is_actors_query: bool, breakdown_values_override: Optional[str | int] = None): + def _breakdown(self, is_actors_query: bool, breakdown_values_override: Optional[str] = None): return Breakdown( team=self.team, query=self.query, diff --git a/posthog/hogql_queries/insights/trends/trends_query_runner.py b/posthog/hogql_queries/insights/trends/trends_query_runner.py index d66110298ffab..d61720740f52b 100644 --- a/posthog/hogql_queries/insights/trends/trends_query_runner.py +++ b/posthog/hogql_queries/insights/trends/trends_query_runner.py @@ -23,9 +23,7 @@ from posthog.hogql.query import execute_hogql_query from posthog.hogql.timings import HogQLTimings from posthog.hogql_queries.insights.trends.breakdown_values import ( - BREAKDOWN_NULL_NUMERIC_LABEL, BREAKDOWN_NULL_STRING_LABEL, - BREAKDOWN_OTHER_NUMERIC_LABEL, BREAKDOWN_OTHER_STRING_LABEL, ) from posthog.hogql_queries.insights.trends.display import TrendsDisplay @@ -175,7 +173,7 @@ def to_actors_query( modifiers=self.modifiers, ) - query = query_builder.build_actors_query(time_frame=time_frame, breakdown_filter=breakdown_value) + query = query_builder.build_actors_query(time_frame=time_frame, breakdown_filter=str(breakdown_value)) return query @@ -240,14 +238,10 @@ def to_actors_query_options(self) -> InsightActorsQueryOptionsResponse: cohort_name = "all users" if str(value) == "0" else Cohort.objects.get(pk=value).name label = cohort_name value = value - elif value == BREAKDOWN_OTHER_STRING_LABEL or value == BREAKDOWN_OTHER_NUMERIC_LABEL: - # label = "Other" - # value = BREAKDOWN_OTHER_STRING_LABEL - continue # TODO: Add support for "other" breakdowns - elif value == BREAKDOWN_NULL_STRING_LABEL or value == BREAKDOWN_NULL_NUMERIC_LABEL: - # label = "Null" - # value = BREAKDOWN_NULL_STRING_LABEL - continue # TODO: Add support for "null" breakdowns + elif value == BREAKDOWN_OTHER_STRING_LABEL: + label = "Other (Groups all remaining values)" + elif value == BREAKDOWN_NULL_STRING_LABEL: + label = "None (No value)" elif is_boolean_breakdown: label = self._convert_boolean(value) else: @@ -501,18 +495,6 @@ def get_value(name: str, val: Any): series_object["breakdown_value"] = remapped_label - # If the breakdown value is the numeric "other", then set it to the string version - if ( - remapped_label == BREAKDOWN_OTHER_NUMERIC_LABEL - or remapped_label == str(BREAKDOWN_OTHER_NUMERIC_LABEL) - or remapped_label == float(BREAKDOWN_OTHER_NUMERIC_LABEL) - ): - series_object["breakdown_value"] = BREAKDOWN_OTHER_STRING_LABEL - if real_series_count > 1 or self._is_breakdown_field_boolean(): - series_object["label"] = "{} - {}".format(series_label or "All events", "Other") - else: - series_object["label"] = "Other" - res.append(series_object) return res From 6eea1a6554b090925f1117e2adee053bc7a37146 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Thu, 21 Mar 2024 23:15:17 +0000 Subject: [PATCH 03/16] chore: only run depot runner comparison when labelled (#21092) * chore: only run depot runner comparison when labelled * fix --- .github/workflows/ci-backend-depot.yml | 10 +--------- .github/workflows/ci-e2e-depot.yml | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-backend-depot.yml b/.github/workflows/ci-backend-depot.yml index 3cf935ced141e..928886d44cf52 100644 --- a/.github/workflows/ci-backend-depot.yml +++ b/.github/workflows/ci-backend-depot.yml @@ -5,15 +5,7 @@ name: Backend CI (depot) on: - push: - branches: - - master pull_request: - workflow_dispatch: - inputs: - clickhouseServerVersion: - description: ClickHouse server version. Leave blank for default - type: string concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -41,7 +33,7 @@ jobs: changes: runs-on: depot-ubuntu-latest-4 timeout-minutes: 5 - if: github.repository == 'PostHog/posthog' + if: ${{ contains(github.event.pull_request.labels.*.name, 'test-depot') }} name: Determine need to run backend checks # Set job outputs to values from filter step outputs: diff --git a/.github/workflows/ci-e2e-depot.yml b/.github/workflows/ci-e2e-depot.yml index 4985dac9d746a..697d42e97f945 100644 --- a/.github/workflows/ci-e2e-depot.yml +++ b/.github/workflows/ci-e2e-depot.yml @@ -16,7 +16,7 @@ jobs: changes: runs-on: depot-ubuntu-latest-4 timeout-minutes: 5 - if: github.repository == 'PostHog/posthog' + if: ${{ contains(github.event.pull_request.labels.*.name, 'test-depot') }} name: Determine need to run E2E checks # Set job outputs to values from filter step outputs: From f43d7a9c7a0089e84ce6670c763358b8723172f1 Mon Sep 17 00:00:00 2001 From: Robbie Date: Fri, 22 Mar 2024 08:15:50 +0000 Subject: [PATCH 04/16] feat(web-analytics): HogQL sessions where extractor (#20986) * Add logic to extract a raw_sessions where clause from a query on the sessions table * Add failing test - need to figure out types * Replace sessions with raw_sessions * Use existing Visitor class hierarchy rather than creating a new one * Clear types * Add working test * Formatting * Fix typing * Better fix typing * Fix tests * Add a big comment * Increase comment * Add types to Visitor * Handles aliases better * Add test for joining events and sessions * Fix typing * More robust way of looking up tables * Add a test to make sure that collapsing ands works --- posthog/hogql/ast.py | 12 + posthog/hogql/base.py | 2 +- posthog/hogql/database/__init__.py | 0 posthog/hogql/database/models.py | 7 +- posthog/hogql/database/schema/__init__.py | 0 .../hogql/database/schema/cohort_people.py | 3 +- posthog/hogql/database/schema/groups.py | 3 +- posthog/hogql/database/schema/log_entries.py | 5 +- .../database/schema/person_distinct_ids.py | 3 +- posthog/hogql/database/schema/persons.py | 4 +- posthog/hogql/database/schema/persons_pdi.py | 3 +- .../database/schema/session_replay_events.py | 3 +- posthog/hogql/database/schema/sessions.py | 15 +- .../hogql/database/schema/util/__init__.py | 0 .../util/session_where_clause_extractor.py | 398 ++++++++++++++++++ .../test_session_where_clause_extractor.py | 284 +++++++++++++ posthog/hogql/test/test_bytecode.py | 2 +- posthog/hogql/test/test_visitor.py | 2 +- posthog/hogql/transforms/lazy_tables.py | 2 +- posthog/hogql/visitor.py | 13 +- 20 files changed, 730 insertions(+), 31 deletions(-) create mode 100644 posthog/hogql/database/__init__.py create mode 100644 posthog/hogql/database/schema/__init__.py create mode 100644 posthog/hogql/database/schema/util/__init__.py create mode 100644 posthog/hogql/database/schema/util/session_where_clause_extractor.py create mode 100644 posthog/hogql/database/schema/util/test/test_session_where_clause_extractor.py diff --git a/posthog/hogql/ast.py b/posthog/hogql/ast.py index a459514f2524f..806226b8f1b9e 100644 --- a/posthog/hogql/ast.py +++ b/posthog/hogql/ast.py @@ -46,8 +46,17 @@ def resolve_constant_type(self, context: HogQLContext): def resolve_database_field(self, context: HogQLContext): if isinstance(self.type, FieldType): return self.type.resolve_database_field(context) + if isinstance(self.type, PropertyType): + return self.type.field_type.resolve_database_field(context) raise NotImplementedException("FieldAliasType.resolve_database_field not implemented") + def resolve_table_type(self, context: HogQLContext): + if isinstance(self.type, FieldType): + return self.type.table_type + if isinstance(self.type, PropertyType): + return self.type.field_type.table_type + raise NotImplementedException("FieldAliasType.resolve_table_type not implemented") + @dataclass(kw_only=True) class BaseTableType(Type): @@ -339,6 +348,9 @@ def get_child(self, name: str | int, context: HogQLContext) -> Type: f'Can not access property "{name}" on field "{self.name}" of type: {type(database_field).__name__}' ) + def resolve_table_type(self, context: HogQLContext): + return self.table_type + @dataclass(kw_only=True) class PropertyType(Type): diff --git a/posthog/hogql/base.py b/posthog/hogql/base.py index fbdafffb2d08c..e8a74025b78be 100644 --- a/posthog/hogql/base.py +++ b/posthog/hogql/base.py @@ -32,7 +32,7 @@ def accept(self, visitor): return visit(self) if hasattr(visitor, "visit_unknown"): return visitor.visit_unknown(self) - raise NotImplementedException(f"Visitor has no method {method_name}") + raise NotImplementedException(f"{visitor.__class__.__name__} has no method {method_name}") @dataclass(kw_only=True) diff --git a/posthog/hogql/database/__init__.py b/posthog/hogql/database/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/posthog/hogql/database/models.py b/posthog/hogql/database/models.py index 95a00595c6472..d2da7868a7f9c 100644 --- a/posthog/hogql/database/models.py +++ b/posthog/hogql/database/models.py @@ -3,7 +3,6 @@ from posthog.hogql.base import Expr from posthog.hogql.errors import HogQLException, NotImplementedException -from posthog.schema import HogQLQueryModifiers if TYPE_CHECKING: from posthog.hogql.context import HogQLContext @@ -126,12 +125,14 @@ def resolve_table(self, context: "HogQLContext") -> Table: class LazyTable(Table): """ - A table that is replaced with a subquery returned from `lazy_select(requested_fields: Dict[name, chain], modifiers: HogQLQueryModifiers)` + A table that is replaced with a subquery returned from `lazy_select(requested_fields: Dict[name, chain], modifiers: HogQLQueryModifiers, node: SelectQuery)` """ model_config = ConfigDict(extra="forbid") - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers) -> Any: + def lazy_select( + self, requested_fields: Dict[str, List[str | int]], context: "HogQLContext", node: "SelectQuery" + ) -> Any: raise NotImplementedException("LazyTable.lazy_select not overridden") diff --git a/posthog/hogql/database/schema/__init__.py b/posthog/hogql/database/schema/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/posthog/hogql/database/schema/cohort_people.py b/posthog/hogql/database/schema/cohort_people.py index 72080419b7355..11723f0194619 100644 --- a/posthog/hogql/database/schema/cohort_people.py +++ b/posthog/hogql/database/schema/cohort_people.py @@ -9,7 +9,6 @@ FieldOrTable, ) from posthog.hogql.database.schema.persons import join_with_persons_table -from posthog.schema import HogQLQueryModifiers COHORT_PEOPLE_FIELDS = { "person_id": StringDatabaseField(name="person_id"), @@ -67,7 +66,7 @@ def to_printed_hogql(self): class CohortPeople(LazyTable): fields: Dict[str, FieldOrTable] = COHORT_PEOPLE_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): return select_from_cohort_people_table(requested_fields) def to_printed_clickhouse(self, context): diff --git a/posthog/hogql/database/schema/groups.py b/posthog/hogql/database/schema/groups.py index bb237d68e8070..3b9de7f08befc 100644 --- a/posthog/hogql/database/schema/groups.py +++ b/posthog/hogql/database/schema/groups.py @@ -13,7 +13,6 @@ FieldOrTable, ) from posthog.hogql.errors import HogQLException -from posthog.schema import HogQLQueryModifiers GROUPS_TABLE_FIELDS = { "index": IntegerDatabaseField(name="group_type_index"), @@ -83,7 +82,7 @@ def to_printed_hogql(self): class GroupsTable(LazyTable): fields: Dict[str, FieldOrTable] = GROUPS_TABLE_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): return select_from_groups_table(requested_fields) def to_printed_clickhouse(self, context): diff --git a/posthog/hogql/database/schema/log_entries.py b/posthog/hogql/database/schema/log_entries.py index c14e90e26da50..9f5dc816ac4b0 100644 --- a/posthog/hogql/database/schema/log_entries.py +++ b/posthog/hogql/database/schema/log_entries.py @@ -9,7 +9,6 @@ LazyTable, FieldOrTable, ) -from posthog.schema import HogQLQueryModifiers LOG_ENTRIES_FIELDS: Dict[str, FieldOrTable] = { "team_id": IntegerDatabaseField(name="team_id"), @@ -35,7 +34,7 @@ def to_printed_hogql(self): class ReplayConsoleLogsLogEntriesTable(LazyTable): fields: Dict[str, FieldOrTable] = LOG_ENTRIES_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): fields: List[ast.Expr] = [ast.Field(chain=["log_entries"] + chain) for name, chain in requested_fields.items()] return ast.SelectQuery( @@ -58,7 +57,7 @@ def to_printed_hogql(self): class BatchExportLogEntriesTable(LazyTable): fields: Dict[str, FieldOrTable] = LOG_ENTRIES_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): fields: List[ast.Expr] = [ast.Field(chain=["log_entries"] + chain) for name, chain in requested_fields.items()] return ast.SelectQuery( diff --git a/posthog/hogql/database/schema/person_distinct_ids.py b/posthog/hogql/database/schema/person_distinct_ids.py index 02144b35fc3d8..3304eccda862e 100644 --- a/posthog/hogql/database/schema/person_distinct_ids.py +++ b/posthog/hogql/database/schema/person_distinct_ids.py @@ -14,7 +14,6 @@ ) from posthog.hogql.database.schema.persons import join_with_persons_table from posthog.hogql.errors import HogQLException -from posthog.schema import HogQLQueryModifiers PERSON_DISTINCT_IDS_FIELDS = { "team_id": IntegerDatabaseField(name="team_id"), @@ -82,7 +81,7 @@ def to_printed_hogql(self): class PersonDistinctIdsTable(LazyTable): fields: Dict[str, FieldOrTable] = PERSON_DISTINCT_IDS_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): return select_from_person_distinct_ids_table(requested_fields) def to_printed_clickhouse(self, context): diff --git a/posthog/hogql/database/schema/persons.py b/posthog/hogql/database/schema/persons.py index a248da56b7307..c7abdd89e14c6 100644 --- a/posthog/hogql/database/schema/persons.py +++ b/posthog/hogql/database/schema/persons.py @@ -123,8 +123,8 @@ def to_printed_hogql(self): class PersonsTable(LazyTable): fields: Dict[str, FieldOrTable] = PERSONS_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): - return select_from_persons_table(requested_fields, modifiers) + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): + return select_from_persons_table(requested_fields, context.modifiers) def to_printed_clickhouse(self, context): return "person" diff --git a/posthog/hogql/database/schema/persons_pdi.py b/posthog/hogql/database/schema/persons_pdi.py index 9f476f407b4d2..195643b90c08c 100644 --- a/posthog/hogql/database/schema/persons_pdi.py +++ b/posthog/hogql/database/schema/persons_pdi.py @@ -10,7 +10,6 @@ FieldOrTable, ) from posthog.hogql.errors import HogQLException -from posthog.schema import HogQLQueryModifiers # :NOTE: We already have person_distinct_ids.py, which most tables link to. This persons_pdi.py is a hack to @@ -63,7 +62,7 @@ class PersonsPDITable(LazyTable): "person_id": StringDatabaseField(name="person_id"), } - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): return persons_pdi_select(requested_fields) def to_printed_clickhouse(self, context): diff --git a/posthog/hogql/database/schema/session_replay_events.py b/posthog/hogql/database/schema/session_replay_events.py index c9d564c7d4588..baaecef89e049 100644 --- a/posthog/hogql/database/schema/session_replay_events.py +++ b/posthog/hogql/database/schema/session_replay_events.py @@ -15,7 +15,6 @@ PersonDistinctIdsTable, join_with_person_distinct_ids_table, ) -from posthog.schema import HogQLQueryModifiers RAW_ONLY_FIELDS = ["min_first_timestamp", "max_last_timestamp"] @@ -115,7 +114,7 @@ class SessionReplayEventsTable(LazyTable): "first_url": StringDatabaseField(name="first_url"), } - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node): return select_from_session_replay_events_table(requested_fields) def to_printed_clickhouse(self, context): diff --git a/posthog/hogql/database/schema/sessions.py b/posthog/hogql/database/schema/sessions.py index 2a4865798eeb8..770daceaa23c5 100644 --- a/posthog/hogql/database/schema/sessions.py +++ b/posthog/hogql/database/schema/sessions.py @@ -1,5 +1,7 @@ from typing import Dict, List, cast +from posthog.hogql import ast +from posthog.hogql.context import HogQLContext from posthog.hogql.database.models import ( StringDatabaseField, DateTimeDatabaseField, @@ -11,7 +13,7 @@ LazyTable, ) from posthog.hogql.database.schema.channel_type import create_channel_type_expr -from posthog.schema import HogQLQueryModifiers +from posthog.hogql.database.schema.util.session_where_clause_extractor import SessionMinTimestampWhereClauseExtractor SESSIONS_COMMON_FIELDS: Dict[str, FieldOrTable] = { @@ -62,7 +64,9 @@ def avoid_asterisk_fields(self) -> List[str]: ] -def select_from_sessions_table(requested_fields: Dict[str, List[str | int]]): +def select_from_sessions_table( + requested_fields: Dict[str, List[str | int]], node: ast.SelectQuery, context: HogQLContext +): from posthog.hogql import ast table_name = "raw_sessions" @@ -134,10 +138,13 @@ def select_from_sessions_table(requested_fields: Dict[str, List[str | int]]): ) group_by_fields.append(ast.Field(chain=cast(list[str | int], [table_name]) + chain)) + where = SessionMinTimestampWhereClauseExtractor(context).get_inner_where(node) + return ast.SelectQuery( select=select_fields, select_from=ast.JoinExpr(table=ast.Field(chain=[table_name])), group_by=group_by_fields, + where=where, ) @@ -148,8 +155,8 @@ class SessionsTable(LazyTable): "channel_type": StringDatabaseField(name="channel_type"), } - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): - return select_from_sessions_table(requested_fields) + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context, node: ast.SelectQuery): + return select_from_sessions_table(requested_fields, node, context) def to_printed_clickhouse(self, context): return "sessions" diff --git a/posthog/hogql/database/schema/util/__init__.py b/posthog/hogql/database/schema/util/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/posthog/hogql/database/schema/util/session_where_clause_extractor.py b/posthog/hogql/database/schema/util/session_where_clause_extractor.py new file mode 100644 index 0000000000000..83933bdde8b85 --- /dev/null +++ b/posthog/hogql/database/schema/util/session_where_clause_extractor.py @@ -0,0 +1,398 @@ +from dataclasses import dataclass +from typing import Optional + +from posthog.hogql import ast +from posthog.hogql.ast import CompareOperationOp, ArithmeticOperationOp +from posthog.hogql.context import HogQLContext +from posthog.hogql.database.models import DatabaseField + +from posthog.hogql.visitor import clone_expr, CloningVisitor, Visitor + +SESSION_BUFFER_DAYS = 3 + + +@dataclass +class SessionMinTimestampWhereClauseExtractor(CloningVisitor): + """This class extracts the Where clause from the lazy sessions table, to the clickhouse sessions table. + + The sessions table in Clickhouse is an AggregatingMergeTree, and will have one row per session per day. This means that + when we want to query sessions, we need to pre-group these rows, so that we only have one row per session. + + We hide this detail using a lazy table, but to make querying the underlying Clickhouse table faster, we can inline the + min_timestamp where conditions from the select on the outer lazy table to the select on the inner real table. + + This class is called on the select query of the lazy table, and will return the where clause that should be applied to + the inner table. + + As a query can be unreasonably complex, we only handle simple cases, but this class is designed to fail-safe. If it + can't reason about a particular expression, it will just return a constant True, i.e. fetch more rows than necessary. + + This means that we can incrementally add support for more complex queries, without breaking existing queries, by + handling more cases. + + Some examples of failing-safe: + + `SELECT * FROM sessions where min_timestamp > '2022-01-01' AND f(session_id)` + only the` min_timestamp > '2022-01-01'` part is relevant, so we can ignore the `f(session_id)` part, and it is safe + to replace it with a constant True, which collapses the AND to just the `min_timestamp > '2022-01-01'` part. + + `SELECT * FROM sessions where min_timestamp > '2022-01-01' OR f(session_id)` + only the` min_timestamp > '2022-01-01'` part is relevant, and turning the `f(session_id)` part into a constant True + would collapse the OR to True. In this case we return None as no pre-filtering is possible. + + All min_timestamp comparisons are given a buffer of SESSION_BUFFER_DAYS each side, to ensure that we collect all the + relevant rows for each session. + """ + + context: HogQLContext + clear_types: bool = False + clear_locations: bool = False + + def get_inner_where(self, parsed_query: ast.SelectQuery) -> Optional[ast.Expr]: + if not parsed_query.where: + return None + + # visit the where clause + where = self.visit(parsed_query.where) + + if isinstance(where, ast.Constant): + return None + + return clone_expr(where, clear_types=True, clear_locations=True) + + def visit_compare_operation(self, node: ast.CompareOperation) -> ast.Expr: + is_left_constant = is_time_or_interval_constant(node.left) + is_right_constant = is_time_or_interval_constant(node.right) + is_left_timestamp_field = is_simple_timestamp_field_expression(node.left, self.context) + is_right_timestamp_field = is_simple_timestamp_field_expression(node.right, self.context) + + if is_left_constant and is_right_constant: + # just ignore this comparison + return ast.Constant(value=True) + + # handle the left side being a min_timestamp expression and the right being constant + if is_left_timestamp_field and is_right_constant: + if node.op == CompareOperationOp.Eq: + return ast.And( + exprs=[ + ast.CompareOperation( + op=ast.CompareOperationOp.LtEq, + left=ast.ArithmeticOperation( + op=ast.ArithmeticOperationOp.Sub, + left=rewrite_timestamp_field(node.left, self.context), + right=ast.Call(name="toIntervalDay", args=[ast.Constant(value=SESSION_BUFFER_DAYS)]), + ), + right=node.right, + ), + ast.CompareOperation( + op=ast.CompareOperationOp.GtEq, + left=ast.ArithmeticOperation( + op=ast.ArithmeticOperationOp.Add, + left=rewrite_timestamp_field(node.left, self.context), + right=ast.Call(name="toIntervalDay", args=[ast.Constant(value=SESSION_BUFFER_DAYS)]), + ), + right=node.right, + ), + ] + ) + elif node.op == CompareOperationOp.Gt or node.op == CompareOperationOp.GtEq: + return ast.CompareOperation( + op=ast.CompareOperationOp.GtEq, + left=ast.ArithmeticOperation( + op=ast.ArithmeticOperationOp.Add, + left=rewrite_timestamp_field(node.left, self.context), + right=ast.Call(name="toIntervalDay", args=[ast.Constant(value=SESSION_BUFFER_DAYS)]), + ), + right=node.right, + ) + elif node.op == CompareOperationOp.Lt or node.op == CompareOperationOp.LtEq: + return ast.CompareOperation( + op=ast.CompareOperationOp.LtEq, + left=ast.ArithmeticOperation( + op=ast.ArithmeticOperationOp.Sub, + left=rewrite_timestamp_field(node.left, self.context), + right=ast.Call(name="toIntervalDay", args=[ast.Constant(value=SESSION_BUFFER_DAYS)]), + ), + right=node.right, + ) + elif is_right_timestamp_field and is_left_constant: + # let's not duplicate the logic above, instead just flip and it and recurse + if node.op in [ + CompareOperationOp.Eq, + CompareOperationOp.Lt, + CompareOperationOp.LtEq, + CompareOperationOp.Gt, + CompareOperationOp.GtEq, + ]: + return self.visit( + ast.CompareOperation( + op=CompareOperationOp.Eq + if node.op == CompareOperationOp.Eq + else CompareOperationOp.Lt + if node.op == CompareOperationOp.Gt + else CompareOperationOp.LtEq + if node.op == CompareOperationOp.GtEq + else CompareOperationOp.Gt + if node.op == CompareOperationOp.Lt + else CompareOperationOp.GtEq, + left=node.right, + right=node.left, + ) + ) + + return ast.Constant(value=True) + + def visit_arithmetic_operation(self, node: ast.ArithmeticOperation) -> ast.Expr: + # don't even try to handle complex logic + return ast.Constant(value=True) + + def visit_not(self, node: ast.Not) -> ast.Expr: + return ast.Constant(value=True) + + def visit_call(self, node: ast.Call) -> ast.Expr: + if node.name == "and": + return self.visit_and(ast.And(exprs=node.args)) + elif node.name == "or": + return self.visit_or(ast.Or(exprs=node.args)) + return ast.Constant(value=True) + + def visit_field(self, node: ast.Field) -> ast.Expr: + return ast.Constant(value=True) + + def visit_constant(self, node: ast.Constant) -> ast.Expr: + return ast.Constant(value=True) + + def visit_placeholder(self, node: ast.Placeholder) -> ast.Expr: + raise Exception() # this should never happen, as placeholders should be resolved before this runs + + def visit_and(self, node: ast.And) -> ast.Expr: + exprs = [self.visit(expr) for expr in node.exprs] + + flattened = [] + for expr in exprs: + if isinstance(expr, ast.And): + flattened.extend(expr.exprs) + else: + flattened.append(expr) + + if any(isinstance(expr, ast.Constant) and expr.value is False for expr in flattened): + return ast.Constant(value=False) + + filtered = [expr for expr in flattened if not isinstance(expr, ast.Constant) or expr.value is not True] + if len(filtered) == 0: + return ast.Constant(value=True) + elif len(filtered) == 1: + return filtered[0] + else: + return ast.And(exprs=filtered) + + def visit_or(self, node: ast.Or) -> ast.Expr: + exprs = [self.visit(expr) for expr in node.exprs] + + flattened = [] + for expr in exprs: + if isinstance(expr, ast.Or): + flattened.extend(expr.exprs) + else: + flattened.append(expr) + + if any(isinstance(expr, ast.Constant) and expr.value is True for expr in flattened): + return ast.Constant(value=True) + + filtered = [expr for expr in flattened if not isinstance(expr, ast.Constant) or expr.value is not False] + if len(filtered) == 0: + return ast.Constant(value=False) + elif len(filtered) == 1: + return filtered[0] + else: + return ast.Or(exprs=filtered) + + def visit_alias(self, node: ast.Alias) -> ast.Expr: + return self.visit(node.expr) + + +def is_time_or_interval_constant(expr: ast.Expr) -> bool: + return IsTimeOrIntervalConstantVisitor().visit(expr) + + +class IsTimeOrIntervalConstantVisitor(Visitor[bool]): + def visit_constant(self, node: ast.Constant) -> bool: + return True + + def visit_compare_operation(self, node: ast.CompareOperation) -> bool: + return self.visit(node.left) and self.visit(node.right) + + def visit_arithmetic_operation(self, node: ast.ArithmeticOperation) -> bool: + return self.visit(node.left) and self.visit(node.right) + + def visit_call(self, node: ast.Call) -> bool: + # some functions just return a constant + if node.name in ["today", "now"]: + return True + # some functions return a constant if the first argument is a constant + if node.name in [ + "parseDateTime64BestEffortOrNull", + "toDateTime", + "toTimeZone", + "assumeNotNull", + "toIntervalYear", + "toIntervalMonth", + "toIntervalWeek", + "toIntervalDay", + "toIntervalHour", + "toIntervalMinute", + "toIntervalSecond", + "toStartOfDay", + "toStartOfWeek", + "toStartOfMonth", + "toStartOfQuarter", + "toStartOfYear", + ]: + return self.visit(node.args[0]) + + if node.name in ["minus", "add"]: + return all(self.visit(arg) for arg in node.args) + + # otherwise we don't know, so return False + return False + + def visit_field(self, node: ast.Field) -> bool: + return False + + def visit_and(self, node: ast.And) -> bool: + return False + + def visit_or(self, node: ast.Or) -> bool: + return False + + def visit_not(self, node: ast.Not) -> bool: + return False + + def visit_placeholder(self, node: ast.Placeholder) -> bool: + raise Exception() + + def visit_alias(self, node: ast.Alias) -> bool: + return self.visit(node.expr) + + +def is_simple_timestamp_field_expression(expr: ast.Expr, context: HogQLContext) -> bool: + return IsSimpleTimestampFieldExpressionVisitor(context).visit(expr) + + +@dataclass +class IsSimpleTimestampFieldExpressionVisitor(Visitor[bool]): + context: HogQLContext + + def visit_constant(self, node: ast.Constant) -> bool: + return False + + def visit_field(self, node: ast.Field) -> bool: + if node.type and isinstance(node.type, ast.FieldType): + resolved_field = node.type.resolve_database_field(self.context) + if resolved_field and isinstance(resolved_field, DatabaseField) and resolved_field: + return resolved_field.name in ["min_timestamp", "timestamp"] + # no type information, so just use the name of the field + return node.chain[-1] in ["min_timestamp", "timestamp"] + + def visit_arithmetic_operation(self, node: ast.ArithmeticOperation) -> bool: + # only allow the min_timestamp field to be used on one side of the arithmetic operation + return ( + self.visit(node.left) + and is_time_or_interval_constant(node.right) + or (self.visit(node.right) and is_time_or_interval_constant(node.left)) + ) + + def visit_call(self, node: ast.Call) -> bool: + # some functions count as a timestamp field expression if their first argument is + if node.name in [ + "parseDateTime64BestEffortOrNull", + "toDateTime", + "toTimeZone", + "assumeNotNull", + "toStartOfDay", + "toStartOfWeek", + "toStartOfMonth", + "toStartOfQuarter", + "toStartOfYear", + ]: + return self.visit(node.args[0]) + + if node.name in ["minus", "add"]: + return self.visit_arithmetic_operation( + ast.ArithmeticOperation( + op=ArithmeticOperationOp.Sub if node.name == "minus" else ArithmeticOperationOp.Add, + left=node.args[0], + right=node.args[1], + ) + ) + + # otherwise we don't know, so return False + return False + + def visit_compare_operation(self, node: ast.CompareOperation) -> bool: + return False + + def visit_and(self, node: ast.And) -> bool: + return False + + def visit_or(self, node: ast.Or) -> bool: + return False + + def visit_not(self, node: ast.Not) -> bool: + return False + + def visit_placeholder(self, node: ast.Placeholder) -> bool: + raise Exception() + + def visit_alias(self, node: ast.Alias) -> bool: + from posthog.hogql.database.schema.events import EventsTable + from posthog.hogql.database.schema.sessions import SessionsTable + + if node.type and isinstance(node.type, ast.FieldAliasType): + resolved_field = node.type.resolve_database_field(self.context) + table_type = node.type.resolve_table_type(self.context) + if not table_type: + return False + return ( + isinstance(table_type, ast.TableType) + and isinstance(table_type.table, EventsTable) + and resolved_field.name == "timestamp" + ) or ( + isinstance(table_type, ast.LazyTableType) + and isinstance(table_type.table, SessionsTable) + and resolved_field.name == "min_timestamp" + ) + + return self.visit(node.expr) + + +def rewrite_timestamp_field(expr: ast.Expr, context: HogQLContext) -> ast.Expr: + return RewriteTimestampFieldVisitor(context).visit(expr) + + +class RewriteTimestampFieldVisitor(CloningVisitor): + context: HogQLContext + + def __init__(self, context: HogQLContext, *args, **kwargs): + super().__init__(*args, **kwargs) + self.context = context + + def visit_field(self, node: ast.Field) -> ast.Field: + from posthog.hogql.database.schema.events import EventsTable + from posthog.hogql.database.schema.sessions import SessionsTable + + if node.type and isinstance(node.type, ast.FieldType): + resolved_field = node.type.resolve_database_field(self.context) + table = node.type.resolve_table_type(self.context).table + if resolved_field and isinstance(resolved_field, DatabaseField): + if (isinstance(table, EventsTable) and resolved_field.name == "timestamp") or ( + isinstance(table, SessionsTable) and resolved_field.name == "min_timestamp" + ): + return ast.Field(chain=["raw_sessions", "min_timestamp"]) + # no type information, so just use the name of the field + if node.chain[-1] in ["min_timestamp", "timestamp"]: + return ast.Field(chain=["raw_sessions", "min_timestamp"]) + return node + + def visit_alias(self, node: ast.Alias) -> ast.Expr: + return self.visit(node.expr) diff --git a/posthog/hogql/database/schema/util/test/test_session_where_clause_extractor.py b/posthog/hogql/database/schema/util/test/test_session_where_clause_extractor.py new file mode 100644 index 0000000000000..bc5324e739ad9 --- /dev/null +++ b/posthog/hogql/database/schema/util/test/test_session_where_clause_extractor.py @@ -0,0 +1,284 @@ +from typing import Union, Optional, Dict + +from posthog.hogql import ast +from posthog.hogql.context import HogQLContext +from posthog.hogql.database.schema.util.session_where_clause_extractor import SessionMinTimestampWhereClauseExtractor +from posthog.hogql.modifiers import create_default_modifiers_for_team +from posthog.hogql.parser import parse_select, parse_expr +from posthog.hogql.printer import prepare_ast_for_printing, print_prepared_ast +from posthog.hogql.visitor import clone_expr +from posthog.test.base import ClickhouseTestMixin, APIBaseTest + + +def f(s: Union[str, ast.Expr, None], placeholders: Optional[dict[str, ast.Expr]] = None) -> Union[ast.Expr, None]: + if s is None: + return None + if isinstance(s, str): + expr = parse_expr(s, placeholders=placeholders) + else: + expr = s + return clone_expr(expr, clear_types=True, clear_locations=True) + + +def parse( + s: str, + placeholders: Optional[Dict[str, ast.Expr]] = None, +) -> ast.SelectQuery: + parsed = parse_select(s, placeholders=placeholders) + assert isinstance(parsed, ast.SelectQuery) + return parsed + + +class TestSessionTimestampInliner(ClickhouseTestMixin, APIBaseTest): + @property + def inliner(self): + team = self.team + modifiers = create_default_modifiers_for_team(team) + context = HogQLContext( + team_id=team.pk, + team=team, + enable_select_queries=True, + modifiers=modifiers, + ) + return SessionMinTimestampWhereClauseExtractor(context) + + def test_handles_select_with_no_where_claus(self): + inner_where = self.inliner.get_inner_where(parse("SELECT * FROM sessions")) + assert inner_where is None + + def test_handles_select_with_eq(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp = '2021-01-01'"))) + expected = f( + "((raw_sessions.min_timestamp - toIntervalDay(3)) <= '2021-01-01') AND ((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-01')" + ) + assert expected == actual + + def test_handles_select_with_eq_flipped(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE '2021-01-01' = min_timestamp"))) + expected = f( + "((raw_sessions.min_timestamp - toIntervalDay(3)) <= '2021-01-01') AND ((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-01')" + ) + assert expected == actual + + def test_handles_select_with_simple_gt(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp > '2021-01-01'"))) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-01')") + assert expected == actual + + def test_handles_select_with_simple_gte(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp >= '2021-01-01'"))) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-01')") + assert expected == actual + + def test_handles_select_with_simple_lt(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp < '2021-01-01'"))) + expected = f("((raw_sessions.min_timestamp - toIntervalDay(3)) <= '2021-01-01')") + assert expected == actual + + def test_handles_select_with_simple_lte(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp <= '2021-01-01'"))) + expected = f("((raw_sessions.min_timestamp - toIntervalDay(3)) <= '2021-01-01')") + assert expected == actual + + def test_select_with_placeholder(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM sessions WHERE min_timestamp > {timestamp}", + placeholders={"timestamp": ast.Constant(value="2021-01-01")}, + ) + ) + ) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-01')") + assert expected == actual + + def test_unrelated_equals(self): + actual = self.inliner.get_inner_where( + parse("SELECT * FROM sessions WHERE initial_utm_campaign = initial_utm_source") + ) + assert actual is None + + def test_timestamp_and(self): + actual = f( + self.inliner.get_inner_where( + parse("SELECT * FROM sessions WHERE and(min_timestamp >= '2021-01-01', min_timestamp <= '2021-01-03')") + ) + ) + expected = f( + "((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-01') AND ((raw_sessions.min_timestamp - toIntervalDay(3)) <= '2021-01-03')" + ) + assert expected == actual + + def test_timestamp_or(self): + actual = f( + self.inliner.get_inner_where( + parse("SELECT * FROM sessions WHERE and(min_timestamp <= '2021-01-01', min_timestamp >= '2021-01-03')") + ) + ) + expected = f( + "((raw_sessions.min_timestamp - toIntervalDay(3)) <= '2021-01-01') AND ((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-03')" + ) + assert expected == actual + + def test_unrelated_function(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE like('a', 'b')"))) + assert actual is None + + def test_timestamp_unrelated_function(self): + actual = f( + self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE like(toString(min_timestamp), 'b')")) + ) + assert actual is None + + def test_timestamp_unrelated_function_timestamp(self): + actual = f( + self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE like(toString(min_timestamp), 'b')")) + ) + assert actual is None + + def test_ambiguous_or(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM sessions WHERE or(min_timestamp > '2021-01-03', like(toString(min_timestamp), 'b'))" + ) + ) + ) + assert actual is None + + def test_ambiguous_and(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM sessions WHERE and(min_timestamp > '2021-01-03', like(toString(min_timestamp), 'b'))" + ) + ) + ) + assert actual == f("(raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-03'") + + def test_join(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM events JOIN sessions ON events.session_id = raw_sessions.session_id WHERE min_timestamp > '2021-01-03'" + ) + ) + ) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-03')") + assert expected == actual + + def test_join_using_events_timestamp_filter(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM events JOIN sessions ON events.session_id = raw_sessions.session_id WHERE timestamp > '2021-01-03'" + ) + ) + ) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= '2021-01-03')") + assert expected == actual + + def test_minus(self): + actual = f(self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp >= today() - 2"))) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= (today() - 2))") + assert expected == actual + + def test_minus_function(self): + actual = f( + self.inliner.get_inner_where(parse("SELECT * FROM sessions WHERE min_timestamp >= minus(today() , 2)")) + ) + expected = f("((raw_sessions.min_timestamp + toIntervalDay(3)) >= minus(today(), 2))") + assert expected == actual + + def test_real_example(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM events JOIN sessions ON events.session_id = raw_sessions.session_id WHERE event = '$pageview' AND toTimeZone(timestamp, 'US/Pacific') >= toDateTime('2024-03-12 00:00:00', 'US/Pacific') AND toTimeZone(timestamp, 'US/Pacific') <= toDateTime('2024-03-19 23:59:59', 'US/Pacific')" + ) + ) + ) + expected = f( + "(toTimeZone(raw_sessions.min_timestamp, 'US/Pacific') + toIntervalDay(3)) >= toDateTime('2024-03-12 00:00:00', 'US/Pacific') AND (toTimeZone(raw_sessions.min_timestamp, 'US/Pacific') - toIntervalDay(3)) <= toDateTime('2024-03-19 23:59:59', 'US/Pacific') " + ) + assert expected == actual + + def test_collapse_and(self): + actual = f( + self.inliner.get_inner_where( + parse( + "SELECT * FROM sesions WHERE event = '$pageview' AND (TRUE AND (TRUE AND TRUE AND (timestamp >= '2024-03-12' AND TRUE)))" + ) + ) + ) + expected = f("(raw_sessions.min_timestamp + toIntervalDay(3)) >= '2024-03-12'") + assert expected == actual + + +class TestSessionsQueriesHogQLToClickhouse(ClickhouseTestMixin, APIBaseTest): + def print_query(self, query: str) -> str: + team = self.team + modifiers = create_default_modifiers_for_team(team) + context = HogQLContext( + team_id=team.pk, + team=team, + enable_select_queries=True, + modifiers=modifiers, + ) + prepared_ast = prepare_ast_for_printing(node=parse(query), context=context, dialect="clickhouse") + pretty = print_prepared_ast(prepared_ast, context=context, dialect="clickhouse", pretty=True) + return pretty + + def test_select_with_timestamp(self): + actual = self.print_query("SELECT session_id FROM sessions WHERE min_timestamp > '2021-01-01'") + expected = f"""SELECT + sessions.session_id AS session_id +FROM + (SELECT + sessions.session_id AS session_id, + min(sessions.min_timestamp) AS min_timestamp + FROM + sessions + WHERE + and(equals(sessions.team_id, {self.team.id}), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, %(hogql_val_0)s), toIntervalDay(3)), %(hogql_val_1)s), 0)) + GROUP BY + sessions.session_id, + sessions.session_id) AS sessions +WHERE + ifNull(greater(toTimeZone(sessions.min_timestamp, %(hogql_val_2)s), %(hogql_val_3)s), 0) +LIMIT 10000""" + assert expected == actual + + def test_join_with_events(self): + actual = self.print_query( + """ +SELECT + sessions.session_id, + uniq(uuid) +FROM events +JOIN sessions +ON events.$session_id = sessions.session_id +WHERE events.timestamp > '2021-01-01' +GROUP BY sessions.session_id +""" + ) + expected = f"""SELECT + sessions.session_id AS session_id, + uniq(events.uuid) +FROM + events + JOIN (SELECT + sessions.session_id AS session_id + FROM + sessions + WHERE + and(equals(sessions.team_id, {self.team.id}), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, %(hogql_val_0)s), toIntervalDay(3)), %(hogql_val_1)s), 0)) + GROUP BY + sessions.session_id, + sessions.session_id) AS sessions ON equals(events.`$session_id`, sessions.session_id) +WHERE + and(equals(events.team_id, {self.team.id}), greater(toTimeZone(events.timestamp, %(hogql_val_2)s), %(hogql_val_3)s)) +GROUP BY + sessions.session_id +LIMIT 10000""" + assert expected == actual diff --git a/posthog/hogql/test/test_bytecode.py b/posthog/hogql/test/test_bytecode.py index cf0b8113b574d..f7d810700e74a 100644 --- a/posthog/hogql/test/test_bytecode.py +++ b/posthog/hogql/test/test_bytecode.py @@ -130,7 +130,7 @@ def test_bytecode_create(self): def test_bytecode_create_error(self): with self.assertRaises(NotImplementedException) as e: to_bytecode("(select 1)") - self.assertEqual(str(e.exception), "Visitor has no method visit_select_query") + self.assertEqual(str(e.exception), "BytecodeBuilder has no method visit_select_query") with self.assertRaises(NotImplementedException) as e: to_bytecode("1 in cohort 2") diff --git a/posthog/hogql/test/test_visitor.py b/posthog/hogql/test/test_visitor.py index 8aa6689328fbf..a01193f788d5f 100644 --- a/posthog/hogql/test/test_visitor.py +++ b/posthog/hogql/test/test_visitor.py @@ -125,7 +125,7 @@ def visit_arithmetic_operation(self, node: ast.ArithmeticOperation): with self.assertRaises(HogQLException) as e: UnknownNotDefinedVisitor().visit(parse_expr("1 + 3 / 'asd2'")) - self.assertEqual(str(e.exception), "Visitor has no method visit_constant") + self.assertEqual(str(e.exception), "UnknownNotDefinedVisitor has no method visit_constant") def test_hogql_exception_start_end(self): class EternalVisitor(TraversingVisitor): diff --git a/posthog/hogql/transforms/lazy_tables.py b/posthog/hogql/transforms/lazy_tables.py index bdbb322d54397..df8ce6962259c 100644 --- a/posthog/hogql/transforms/lazy_tables.py +++ b/posthog/hogql/transforms/lazy_tables.py @@ -309,7 +309,7 @@ def create_override(table_name: str, field_chain: List[str | int]) -> None: # For all the collected tables, create the subqueries, and add them to the table. for table_name, table_to_add in tables_to_add.items(): - subquery = table_to_add.lazy_table.lazy_select(table_to_add.fields_accessed, self.context.modifiers) + subquery = table_to_add.lazy_table.lazy_select(table_to_add.fields_accessed, self.context, node=node) subquery = cast(ast.SelectQuery, clone_expr(subquery, clear_locations=True)) subquery = cast(ast.SelectQuery, resolve_types(subquery, self.context, self.dialect, [node.type])) old_table_type = select_type.tables[table_name] diff --git a/posthog/hogql/visitor.py b/posthog/hogql/visitor.py index c11856169297f..2bf968abf2ab0 100644 --- a/posthog/hogql/visitor.py +++ b/posthog/hogql/visitor.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, TypeVar, Generic, Any from posthog.hogql import ast from posthog.hogql.base import AST, Expr @@ -14,8 +14,11 @@ def clear_locations(expr: Expr) -> Expr: return CloningVisitor(clear_locations=True).visit(expr) -class Visitor(object): - def visit(self, node: AST): +T = TypeVar("T") + + +class Visitor(Generic[T]): + def visit(self, node: AST) -> T: if node is None: return node @@ -28,7 +31,7 @@ def visit(self, node: AST): raise e -class TraversingVisitor(Visitor): +class TraversingVisitor(Visitor[None]): """Visitor that traverses the AST tree without returning anything""" def visit_expr(self, node: Expr): @@ -258,7 +261,7 @@ def visit_hogqlx_attribute(self, node: ast.HogQLXAttribute): self.visit(node.value) -class CloningVisitor(Visitor): +class CloningVisitor(Visitor[Any]): """Visitor that traverses and clones the AST tree. Clears types.""" def __init__( From 5ae6b301208b766523dc22d33f3938f1b70eb890 Mon Sep 17 00:00:00 2001 From: Eric Duong Date: Fri, 22 Mar 2024 04:39:20 -0400 Subject: [PATCH 05/16] chore(data-warehouse): join UI cleanup (#21085) * add loading indicator * add custom settings * update sizing --- .../scenes/data-warehouse/ViewLinkModal.tsx | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/frontend/src/scenes/data-warehouse/ViewLinkModal.tsx b/frontend/src/scenes/data-warehouse/ViewLinkModal.tsx index 2116d2da6e74d..11f50ca4f0d27 100644 --- a/frontend/src/scenes/data-warehouse/ViewLinkModal.tsx +++ b/frontend/src/scenes/data-warehouse/ViewLinkModal.tsx @@ -1,6 +1,6 @@ import './ViewLinkModal.scss' -import { IconTrash } from '@posthog/icons' +import { IconCollapse, IconExpand, IconTrash } from '@posthog/icons' import { LemonButton, LemonDivider, @@ -35,7 +35,7 @@ export function ViewLinkModal(): JSX.Element { } isOpen={isJoinTableModalOpen} onClose={toggleJoinTableModal} - width={600} + width={700} > @@ -57,6 +57,7 @@ export function ViewLinkForm(): JSX.Element { selectedJoiningKey, sourceIsUsingHogQLExpression, joiningIsUsingHogQLExpression, + isViewLinkSubmitting, } = useValues(viewLinkLogic) const { selectJoiningTable, @@ -66,12 +67,13 @@ export function ViewLinkForm(): JSX.Element { selectSourceKey, selectJoiningKey, } = useActions(viewLinkLogic) + const [advancedSettingsExpanded, setAdvancedSettingsExpanded] = useState(false) return (
-
+
Source Table {isNewJoin ? ( @@ -86,7 +88,7 @@ export function ViewLinkForm(): JSX.Element { selectedSourceTableName ?? '' )}
-
+
Joining Table
-
-
+
+
Source Table Key <> @@ -124,7 +126,7 @@ export function ViewLinkForm(): JSX.Element {
-
+
Joining Table Key <> @@ -148,8 +150,22 @@ export function ViewLinkForm(): JSX.Element {
{sqlCodeSnippet && ( - <> +
+ setAdvancedSettingsExpanded(!advancedSettingsExpanded)} + sideIcon={advancedSettingsExpanded ? : } + > +
+

Advanced settings

+
Customize how the fields are accessed
+
+
+
+ )} + {sqlCodeSnippet && advancedSettingsExpanded && ( + <>
Field Name @@ -185,7 +201,7 @@ export function ViewLinkForm(): JSX.Element { Close - + Save
From 5f4cb5486187e4167b53b1131e2272c7fcf9aae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Fri, 22 Mar 2024 09:58:51 +0100 Subject: [PATCH 06/16] fix: Track last updated at for batch export run (#21082) --- posthog/batch_exports/service.py | 16 +++++++++++++--- posthog/temporal/batch_exports/batch_exports.py | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/posthog/batch_exports/service.py b/posthog/batch_exports/service.py index c26be9a77ed1a..b00f0f4c98c69 100644 --- a/posthog/batch_exports/service.py +++ b/posthog/batch_exports/service.py @@ -439,8 +439,11 @@ def create_batch_export_run( return run -def update_batch_export_run_status( - run_id: UUID, status: str, latest_error: str | None, records_completed: int = 0 +def update_batch_export_run( + run_id: UUID, + status: str, + latest_error: str | None, + records_completed: int = 0, ) -> BatchExportRun: """Update the status of an BatchExportRun with given id. @@ -448,7 +451,14 @@ def update_batch_export_run_status( id: The id of the BatchExportRun to update. """ model = BatchExportRun.objects.filter(id=run_id) - updated = model.update(status=status, latest_error=latest_error, records_completed=records_completed) + update_at = dt.datetime.now() + + updated = model.update( + status=status, + latest_error=latest_error, + records_completed=records_completed, + last_updated_at=update_at, + ) if not updated: raise ValueError(f"BatchExportRun with id {run_id} not found.") diff --git a/posthog/temporal/batch_exports/batch_exports.py b/posthog/temporal/batch_exports/batch_exports.py index c776e1f245ef3..c40950c654426 100644 --- a/posthog/temporal/batch_exports/batch_exports.py +++ b/posthog/temporal/batch_exports/batch_exports.py @@ -22,7 +22,7 @@ create_batch_export_backfill, create_batch_export_run, update_batch_export_backfill_status, - update_batch_export_run_status, + update_batch_export_run, ) from posthog.temporal.batch_exports.metrics import ( get_export_finished_metric, @@ -542,7 +542,7 @@ async def update_export_run_status(inputs: UpdateBatchExportRunStatusInputs) -> """Activity that updates the status of an BatchExportRun.""" logger = await bind_temporal_worker_logger(team_id=inputs.team_id) - batch_export_run = await sync_to_async(update_batch_export_run_status)( + batch_export_run = await sync_to_async(update_batch_export_run)( run_id=uuid.UUID(inputs.id), status=inputs.status, latest_error=inputs.latest_error, From 6b6d40a66607adc55f461b05de4c4057255f5c59 Mon Sep 17 00:00:00 2001 From: David Newell Date: Fri, 22 Mar 2024 10:20:37 +0000 Subject: [PATCH 07/16] feat: sparkline errors (#21081) * feat: errors page playlist link * feat: create playlist from errors * remove sample data * update title * add frontend protection to samples * feat: sparkline errors --- ee/session_recordings/ai/error_clustering.py | 15 ++++++++++++--- .../errors/SessionRecordingErrors.tsx | 12 ++++++++++++ frontend/src/types.ts | 1 + 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ee/session_recordings/ai/error_clustering.py b/ee/session_recordings/ai/error_clustering.py index edc06ff471355..7a3c12c44dec0 100644 --- a/ee/session_recordings/ai/error_clustering.py +++ b/ee/session_recordings/ai/error_clustering.py @@ -6,6 +6,7 @@ import pandas as pd import numpy as np from posthog.session_recordings.models.session_recording_event import SessionRecordingViewed +from datetime import date CLUSTER_REPLAY_ERRORS_TIMING = Histogram( "posthog_session_recordings_cluster_replay_errors", @@ -30,7 +31,7 @@ def error_clustering(team: Team, user: User): if not results: return [] - df = pd.DataFrame(results, columns=["session_id", "input", "embeddings"]) + df = pd.DataFrame(results, columns=["session_id", "error", "embeddings", "timestamp"]) df["cluster"] = cluster_embeddings(df["embeddings"].tolist()) @@ -42,7 +43,7 @@ def error_clustering(team: Team, user: User): def fetch_error_embeddings(team_id: int): query = """ SELECT - session_id, input, embeddings + session_id, input, embeddings, generation_timestamp FROM session_replay_embeddings WHERE @@ -76,13 +77,21 @@ def construct_response(df: pd.DataFrame, team: Team, user: User): clusters = [] for cluster, rows in df.groupby("cluster"): session_ids = rows["session_id"].unique() - sample = rows.sample(n=1)[["session_id", "input"]].rename(columns={"input": "error"}).to_dict("records")[0] + sample = rows.sample(n=1)[["session_id", "error"]].to_dict("records")[0] + + date_series = ( + df.groupby([df["timestamp"].dt.date]) + .size() + .reindex(pd.date_range(end=date.today(), periods=7), fill_value=0) + ) + sparkline = dict(zip(date_series.index.astype(str), date_series)) clusters.append( { "cluster": cluster, "sample": sample.get("error"), "session_ids": np.random.choice(session_ids, size=DBSCAN_MIN_SAMPLES - 1), "occurrences": rows.size, + "sparkline": sparkline, "unique_sessions": len(session_ids), "viewed": len(np.intersect1d(session_ids, viewed_session_ids, assume_unique=True)), } diff --git a/frontend/src/scenes/session-recordings/errors/SessionRecordingErrors.tsx b/frontend/src/scenes/session-recordings/errors/SessionRecordingErrors.tsx index 4b2dd2d1abed3..8b73fbcc1f924 100644 --- a/frontend/src/scenes/session-recordings/errors/SessionRecordingErrors.tsx +++ b/frontend/src/scenes/session-recordings/errors/SessionRecordingErrors.tsx @@ -2,6 +2,7 @@ import { IconFeatures } from '@posthog/icons' import { LemonButton, LemonTable, LemonTabs, Spinner } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { JSONViewer } from 'lib/components/JSONViewer' +import { Sparkline } from 'lib/lemon-ui/Sparkline' import { useState } from 'react' import { urls } from 'scenes/urls' @@ -45,6 +46,17 @@ export function SessionRecordingErrors(): JSX.Element { }, width: '50%', }, + { + title: '', + render: (_, cluster) => { + return ( + + ) + }, + }, { title: 'Occurrences', dataIndex: 'occurrences', diff --git a/frontend/src/types.ts b/frontend/src/types.ts index a7f65e84c5473..be96494253ae8 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -906,6 +906,7 @@ export type ErrorCluster = { sample: string occurrences: number session_ids: string[] + sparkline: Record unique_sessions: number viewed: number } From 3a995a5f9ecad0b1463d6e2f9818538946175d64 Mon Sep 17 00:00:00 2001 From: PostHog Bot <69588470+posthog-bot@users.noreply.github.com> Date: Fri, 22 Mar 2024 07:11:01 -0400 Subject: [PATCH 08/16] chore(deps): Update posthog-js to 1.116.4 (#21098) --- package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 79946a087fbf4..2128fa3207a76 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,7 @@ "pmtiles": "^2.11.0", "postcss": "^8.4.31", "postcss-preset-env": "^9.3.0", - "posthog-js": "1.116.3", + "posthog-js": "1.116.4", "posthog-js-lite": "2.5.0", "prettier": "^2.8.8", "prop-types": "^15.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7fc1d7cbd22a4..04806adc67be8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -254,8 +254,8 @@ dependencies: specifier: ^9.3.0 version: 9.3.0(postcss@8.4.31) posthog-js: - specifier: 1.116.3 - version: 1.116.3 + specifier: 1.116.4 + version: 1.116.4 posthog-js-lite: specifier: 2.5.0 version: 2.5.0 @@ -6796,7 +6796,7 @@ packages: '@storybook/csf': 0.1.3 '@storybook/global': 5.0.0 '@storybook/types': 7.6.17 - '@types/qs': 6.9.13 + '@types/qs': 6.9.14 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 @@ -8200,8 +8200,8 @@ packages: resolution: {integrity: sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==} dev: false - /@types/qs@6.9.13: - resolution: {integrity: sha512-iLR+1vTTJ3p0QaOUq6ACbY1mzKTODFDT/XedZI8BksOotFmL4ForwDfRQ/DZeuTHR7/2i4lI1D203gdfxuqTlA==} + /@types/qs@6.9.14: + resolution: {integrity: sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==} dev: true /@types/query-selector-shadow-dom@1.0.0: @@ -17454,8 +17454,8 @@ packages: resolution: {integrity: sha512-Urvlp0Vu9h3td0BVFWt0QXFJDoOZcaAD83XM9d91NKMKTVPZtfU0ysoxstIf5mw/ce9ZfuMgpWPaagrZI4rmSg==} dev: false - /posthog-js@1.116.3: - resolution: {integrity: sha512-KakGsQ8rS/K/U5Q/tiBrRrFRCgGrR0oI9VSYw9hwNCY00EClwAU3EuykUuQTFdQ1EuYMrZDIMWDD4NW6zgf7wQ==} + /posthog-js@1.116.4: + resolution: {integrity: sha512-PZg208/k5OZRQbd9tnGvUgtyRl1IAYyyh74teyIDIH3EnlsAolBlVM4gcoyEYoVkUi5sZLKitj9gTX3/vnEG4Q==} dependencies: fflate: 0.4.8 preact: 10.20.0 From d5cc9e43b9e940faa856be6504932569f8f8e1f8 Mon Sep 17 00:00:00 2001 From: Ben White Date: Fri, 22 Mar 2024 12:28:09 +0100 Subject: [PATCH 09/16] fix: Toolbar better auth issue (#21096) --- ...s-other-toolbar--unauthenticated--dark.png | Bin 10791 -> 12371 bytes ...-other-toolbar--unauthenticated--light.png | Bin 12070 -> 13639 bytes frontend/src/toolbar/bar/Toolbar.scss | 4 - frontend/src/toolbar/bar/Toolbar.tsx | 39 ++++++-- frontend/src/toolbar/bar/ToolbarButton.scss | 11 +++ frontend/src/toolbar/bar/ToolbarButton.tsx | 13 ++- .../src/toolbar/flags/flagsToolbarLogic.ts | 5 - frontend/src/toolbar/toolbarConfigLogic.ts | 6 +- frontend/src/toolbar/toolbarLogic.ts | 87 ------------------ 9 files changed, 53 insertions(+), 112 deletions(-) delete mode 100644 frontend/src/toolbar/toolbarLogic.ts diff --git a/frontend/__snapshots__/scenes-other-toolbar--unauthenticated--dark.png b/frontend/__snapshots__/scenes-other-toolbar--unauthenticated--dark.png index f5283e47bdf438cc2f95a77a1b24ccc90adc38b9..dc149beabe2037e498026227fe248d0fa4cac62c 100644 GIT binary patch literal 12371 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 diff --git a/frontend/__snapshots__/scenes-other-toolbar--unauthenticated--light.png b/frontend/__snapshots__/scenes-other-toolbar--unauthenticated--light.png index 15b96030b8a254d62484aa97934a3972fea6d9b8..ace3a2b7f937317a2e0525ef4a80cbf46ae0220b 100644 GIT binary patch literal 13639 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 TPFNd4G#+Mm&hZz(YJU4456HRb literal 12070 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 PwX*r$?l=6eUibb7qA3my diff --git a/frontend/src/toolbar/bar/Toolbar.scss b/frontend/src/toolbar/bar/Toolbar.scss index ff83b7c9d922a..ec98167332fbd 100644 --- a/frontend/src/toolbar/bar/Toolbar.scss +++ b/frontend/src/toolbar/bar/Toolbar.scss @@ -144,8 +144,4 @@ transform: var(--toolbar-translate) scale(0); } } - - &--unauthenticated { - width: calc(5rem + 1px); // Account for border - } } diff --git a/frontend/src/toolbar/bar/Toolbar.tsx b/frontend/src/toolbar/bar/Toolbar.tsx index f255ccc26800d..8ed031f904d86 100644 --- a/frontend/src/toolbar/bar/Toolbar.tsx +++ b/frontend/src/toolbar/bar/Toolbar.tsx @@ -77,15 +77,18 @@ function MoreMenu(): JSX.Element { } maxContentWidth={true} > - } title="More options" /> + + + ) } -export function ToolbarInfoMenu(): JSX.Element { +export function ToolbarInfoMenu(): JSX.Element | null { const ref = useRef(null) const { visibleMenu, isDragging, menuProperties, minimized, isBlurred } = useValues(toolbarLogic) const { setMenu } = useActions(toolbarLogic) + const { isAuthenticated } = useValues(toolbarConfigLogic) const content = minimized ? null : visibleMenu === 'flags' ? ( @@ -102,6 +105,10 @@ export function ToolbarInfoMenu(): JSX.Element { return () => setMenu(null) }, [ref.current]) + if (!isAuthenticated) { + return null + } + return (
} onClick={isAuthenticated ? toggleMinimized : authenticate} title={isAuthenticated ? 'Minimize' : 'Authenticate the PostHog Toolbar'} titleMinimized={isAuthenticated ? 'Expand the toolbar' : 'Authenticate the PostHog Toolbar'} - /> + > + + {isAuthenticated ? ( <> - } menuId="inspect" /> - } menuId="heatmap" /> - } menuId="actions" /> - } menuId="flags" title="Feature flags" /> + + + + + + + + + + + + - ) : null} + ) : ( + + Authenticate + + )}
diff --git a/frontend/src/toolbar/bar/ToolbarButton.scss b/frontend/src/toolbar/bar/ToolbarButton.scss index 0d0bb666fa540..ce480f3fbab35 100644 --- a/frontend/src/toolbar/bar/ToolbarButton.scss +++ b/frontend/src/toolbar/bar/ToolbarButton.scss @@ -15,6 +15,8 @@ width: 2rem; height: 2rem; min-height: var(--lemon-button-height); + margin: 0.25rem; + font-weight: 600; color: var(--muted-alt); appearance: none !important; // Important as this gets overridden by Ant styles... cursor: pointer; @@ -43,4 +45,13 @@ } } } + + &--flex { + flex-grow: 1; + width: auto; + + button { + width: 100%; + } + } } diff --git a/frontend/src/toolbar/bar/ToolbarButton.tsx b/frontend/src/toolbar/bar/ToolbarButton.tsx index add0e5f2580ce..f5dfc755be469 100644 --- a/frontend/src/toolbar/bar/ToolbarButton.tsx +++ b/frontend/src/toolbar/bar/ToolbarButton.tsx @@ -10,17 +10,18 @@ import React from 'react' import { MenuState, toolbarLogic } from './toolbarLogic' export type ToolbarButtonProps = { - icon: React.ReactElement | null + children: React.ReactNode onClick?: () => void title?: string titleMinimized?: JSX.Element | string menuId?: MenuState + flex?: boolean } export const ToolbarButton: FunctionComponent = React.forwardRef< HTMLDivElement, ToolbarButtonProps ->(({ icon, title, onClick, titleMinimized, menuId, ...props }, ref): JSX.Element => { +>(({ children, title, onClick, titleMinimized, menuId, flex, ...props }, ref): JSX.Element => { const { visibleMenu, minimized, isDragging } = useValues(toolbarLogic) const { setVisibleMenu } = useActions(toolbarLogic) @@ -54,9 +55,13 @@ export const ToolbarButton: FunctionComponent = React.forwar } const theButton = ( -
+
) diff --git a/frontend/src/toolbar/flags/flagsToolbarLogic.ts b/frontend/src/toolbar/flags/flagsToolbarLogic.ts index 60c1f568f45a6..e1f41cabca73c 100644 --- a/frontend/src/toolbar/flags/flagsToolbarLogic.ts +++ b/frontend/src/toolbar/flags/flagsToolbarLogic.ts @@ -40,11 +40,6 @@ export const flagsToolbarLogic = kea([ `/api/projects/@current/feature_flags/my_flags${encodeParams(params, '?')}` ) - if (response.status >= 400) { - toolbarConfigLogic.actions.tokenExpired() - return [] - } - breakpoint() if (!response.ok) { return [] diff --git a/frontend/src/toolbar/toolbarConfigLogic.ts b/frontend/src/toolbar/toolbarConfigLogic.ts index 1b4638b8f39f8..853b03bdeea32 100644 --- a/frontend/src/toolbar/toolbarConfigLogic.ts +++ b/frontend/src/toolbar/toolbarConfigLogic.ts @@ -119,10 +119,12 @@ export async function toolbarFetch( }) if (response.status === 403) { const responseData = await response.json() - // Do not try to authenticate if the user has no project access altogether - if (responseData.detail !== "You don't have access to the project.") { + if (responseData.detail === "You don't have access to the project.") { toolbarConfigLogic.actions.authenticate() } } + if (response.status == 401) { + toolbarConfigLogic.actions.tokenExpired() + } return response } diff --git a/frontend/src/toolbar/toolbarLogic.ts b/frontend/src/toolbar/toolbarLogic.ts deleted file mode 100644 index d5183a6734f20..0000000000000 --- a/frontend/src/toolbar/toolbarLogic.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { actions, afterMount, kea, listeners, path, props, reducers, selectors } from 'kea' -import { lemonToast } from 'lib/lemon-ui/LemonToast/LemonToast' - -import { actionsTabLogic } from '~/toolbar/actions/actionsTabLogic' -import { posthog } from '~/toolbar/posthog' -import { clearSessionToolbarToken } from '~/toolbar/utils' -import { ToolbarProps } from '~/types' - -import type { toolbarLogicType } from './toolbarLogicType' - -export const toolbarLogic = kea([ - path(['toolbar', 'toolbarLogic']), - props({} as ToolbarProps), - - actions({ - authenticate: true, - logout: true, - tokenExpired: true, - processUserIntent: true, - clearUserIntent: true, - showButton: true, - hideButton: true, - }), - - reducers(({ props }) => ({ - rawApiURL: [props.apiURL as string], - rawJsURL: [(props.jsURL || props.apiURL) as string], - temporaryToken: [props.temporaryToken || null, { logout: () => null, tokenExpired: () => null }], - actionId: [props.actionId || null, { logout: () => null, clearUserIntent: () => null }], - userIntent: [props.userIntent || null, { logout: () => null, clearUserIntent: () => null }], - source: [props.source || null, { logout: () => null }], - buttonVisible: [true, { showButton: () => true, hideButton: () => false, logout: () => false }], - dataAttributes: [props.dataAttributes || []], - posthog: [props.posthog ?? null], - })), - - selectors({ - apiURL: [(s) => [s.rawApiURL], (apiURL) => `${apiURL.endsWith('/') ? apiURL.replace(/\/+$/, '') : apiURL}`], - jsURL: [ - (s) => [s.rawJsURL, s.apiURL], - (rawJsURL, apiUrl) => - `${rawJsURL ? (rawJsURL.endsWith('/') ? rawJsURL.replace(/\/+$/, '') : rawJsURL) : apiUrl}`, - ], - isAuthenticated: [(s) => [s.temporaryToken], (temporaryToken) => !!temporaryToken], - }), - - listeners(({ values, props }) => ({ - authenticate: () => { - posthog.capture('toolbar authenticate', { is_authenticated: values.isAuthenticated }) - const encodedUrl = encodeURIComponent(window.location.href) - window.location.href = `${values.apiURL}/authorize_and_redirect/?redirect=${encodedUrl}` - clearSessionToolbarToken() - }, - logout: () => { - posthog.capture('toolbar logout') - clearSessionToolbarToken() - }, - tokenExpired: () => { - posthog.capture('toolbar token expired') - console.warn('PostHog Toolbar API token expired. Clearing session.') - if (values.source !== 'localstorage') { - lemonToast.error('PostHog Toolbar API token expired.') - } - clearSessionToolbarToken() - }, - processUserIntent: () => { - if (props.userIntent === 'add-action' || props.userIntent === 'edit-action') { - actionsTabLogic.actions.showButtonActions() - // the right view will next be opened in `actionsTabLogic` on `getActionsSuccess` - } - }, - })), - - afterMount(({ props, actions, values }) => { - if (props.instrument) { - const distinctId = props.distinctId - if (distinctId) { - posthog.identify(distinctId, props.userEmail ? { email: props.userEmail } : {}) - } - posthog.optIn() - } - if (props.userIntent) { - actions.processUserIntent() - } - posthog.capture('toolbar loaded', { is_authenticated: values.isAuthenticated }) - }), -]) From 7c0258cc0e5a346736fdf4a67801810a49b8d8d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Fri, 22 Mar 2024 14:20:13 +0100 Subject: [PATCH 10/16] refactor: Support for multiple file formats in S3 batch exports (#20979) * refactor: Support for multiple file formats in batch exports * refactor: Prefer composition over inheritance * refactor: More clearly separate writer from temporary file We now should be more explicit about what is the context in which the batch export temporary file is alive. The writer outlives this context, so it can be used by callers to, for example, check how many records were written. * test: More parquet testing * Update query snapshots * fix: Typing * refactor: Move temporary file to new module * test: Add writer classes tests and docstrings * feat: Add new type aliases and docstrings for FlushCallable * refactor: Get rid of ensure close method * fix: Use proper 'none' compression * refactor: Cover all possible file formats with FILE_FORMAT_EXTENSIONS.keys() * test: Also check if bucket name is set to use S3 * feat: Typing and docstring for get_batch_export_writer --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- posthog/batch_exports/service.py | 1 + .../test/__snapshots__/test_in_cohort.ambr | 8 +- .../temporal/batch_exports/batch_exports.py | 201 ------- .../batch_exports/bigquery_batch_export.py | 4 +- .../batch_exports/http_batch_export.py | 6 +- .../batch_exports/postgres_batch_export.py | 4 +- .../temporal/batch_exports/s3_batch_export.py | 203 +++++-- .../batch_exports/snowflake_batch_export.py | 4 +- .../temporal/batch_exports/temporary_file.py | 528 ++++++++++++++++++ .../tests/batch_exports/test_batch_exports.py | 182 ------ .../test_s3_batch_export_workflow.py | 159 +++++- .../batch_exports/test_temporary_file.py | 389 +++++++++++++ 12 files changed, 1238 insertions(+), 451 deletions(-) create mode 100644 posthog/temporal/batch_exports/temporary_file.py create mode 100644 posthog/temporal/tests/batch_exports/test_temporary_file.py diff --git a/posthog/batch_exports/service.py b/posthog/batch_exports/service.py index b00f0f4c98c69..d51dfdb2fbc3c 100644 --- a/posthog/batch_exports/service.py +++ b/posthog/batch_exports/service.py @@ -90,6 +90,7 @@ class S3BatchExportInputs: kms_key_id: str | None = None batch_export_schema: BatchExportSchema | None = None endpoint_url: str | None = None + file_format: str = "JSONLines" @dataclass diff --git a/posthog/hogql/transforms/test/__snapshots__/test_in_cohort.ambr b/posthog/hogql/transforms/test/__snapshots__/test_in_cohort.ambr index 9ff7f8ee0ab49..e0f5ea847110d 100644 --- a/posthog/hogql/transforms/test/__snapshots__/test_in_cohort.ambr +++ b/posthog/hogql/transforms/test/__snapshots__/test_in_cohort.ambr @@ -31,7 +31,7 @@ FROM events LEFT JOIN ( SELECT person_static_cohort.person_id AS cohort_person_id, 1 AS matched, person_static_cohort.cohort_id AS cohort_id FROM person_static_cohort - WHERE and(equals(person_static_cohort.team_id, 420), in(person_static_cohort.cohort_id, [12]))) AS __in_cohort ON equals(__in_cohort.cohort_person_id, events.person_id) + WHERE and(equals(person_static_cohort.team_id, 420), in(person_static_cohort.cohort_id, [11]))) AS __in_cohort ON equals(__in_cohort.cohort_person_id, events.person_id) WHERE and(equals(events.team_id, 420), 1, ifNull(equals(__in_cohort.matched, 1), 0)) LIMIT 100 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1 @@ -42,7 +42,7 @@ FROM events LEFT JOIN ( SELECT person_id AS cohort_person_id, 1 AS matched, cohort_id FROM static_cohort_people - WHERE in(cohort_id, [12])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id) + WHERE in(cohort_id, [11])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id) WHERE and(1, equals(__in_cohort.matched, 1)) LIMIT 100 ''' @@ -55,7 +55,7 @@ FROM events LEFT JOIN ( SELECT person_static_cohort.person_id AS cohort_person_id, 1 AS matched, person_static_cohort.cohort_id AS cohort_id FROM person_static_cohort - WHERE and(equals(person_static_cohort.team_id, 420), in(person_static_cohort.cohort_id, [13]))) AS __in_cohort ON equals(__in_cohort.cohort_person_id, events.person_id) + WHERE and(equals(person_static_cohort.team_id, 420), in(person_static_cohort.cohort_id, [12]))) AS __in_cohort ON equals(__in_cohort.cohort_person_id, events.person_id) WHERE and(equals(events.team_id, 420), 1, ifNull(equals(__in_cohort.matched, 1), 0)) LIMIT 100 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1 @@ -66,7 +66,7 @@ FROM events LEFT JOIN ( SELECT person_id AS cohort_person_id, 1 AS matched, cohort_id FROM static_cohort_people - WHERE in(cohort_id, [13])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id) + WHERE in(cohort_id, [12])) AS __in_cohort ON equals(__in_cohort.cohort_person_id, person_id) WHERE and(1, equals(__in_cohort.matched, 1)) LIMIT 100 ''' diff --git a/posthog/temporal/batch_exports/batch_exports.py b/posthog/temporal/batch_exports/batch_exports.py index c40950c654426..88cf9e32f274f 100644 --- a/posthog/temporal/batch_exports/batch_exports.py +++ b/posthog/temporal/batch_exports/batch_exports.py @@ -1,15 +1,10 @@ import collections.abc -import csv import dataclasses import datetime as dt -import gzip -import tempfile import typing import uuid from string import Template -import brotli -import orjson import pyarrow as pa from asgiref.sync import sync_to_async from django.conf import settings @@ -286,202 +281,6 @@ def get_data_interval(interval: str, data_interval_end: str | None) -> tuple[dt. return (data_interval_start_dt, data_interval_end_dt) -def json_dumps_bytes(d) -> bytes: - return orjson.dumps(d, default=str) - - -class BatchExportTemporaryFile: - """A TemporaryFile used to as an intermediate step while exporting data. - - This class does not implement the file-like interface but rather passes any calls - to the underlying tempfile.NamedTemporaryFile. We do override 'write' methods - to allow tracking bytes and records. - """ - - def __init__( - self, - mode: str = "w+b", - buffering=-1, - compression: str | None = None, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - *, - errors: str | None = None, - ): - self._file = tempfile.NamedTemporaryFile( - mode=mode, - encoding=encoding, - newline=newline, - buffering=buffering, - suffix=suffix, - prefix=prefix, - dir=dir, - errors=errors, - ) - self.compression = compression - self.bytes_total = 0 - self.records_total = 0 - self.bytes_since_last_reset = 0 - self.records_since_last_reset = 0 - self._brotli_compressor = None - - def __getattr__(self, name): - """Pass get attr to underlying tempfile.NamedTemporaryFile.""" - return self._file.__getattr__(name) - - def __enter__(self): - """Context-manager protocol enter method.""" - self._file.__enter__() - return self - - def __exit__(self, exc, value, tb): - """Context-manager protocol exit method.""" - return self._file.__exit__(exc, value, tb) - - def __iter__(self): - yield from self._file - - @property - def brotli_compressor(self): - if self._brotli_compressor is None: - self._brotli_compressor = brotli.Compressor() - return self._brotli_compressor - - def compress(self, content: bytes | str) -> bytes: - if isinstance(content, str): - encoded = content.encode("utf-8") - else: - encoded = content - - match self.compression: - case "gzip": - return gzip.compress(encoded) - case "brotli": - self.brotli_compressor.process(encoded) - return self.brotli_compressor.flush() - case None: - return encoded - case _: - raise ValueError(f"Unsupported compression: '{self.compression}'") - - def write(self, content: bytes | str): - """Write bytes to underlying file keeping track of how many bytes were written.""" - compressed_content = self.compress(content) - - if "b" in self.mode: - result = self._file.write(compressed_content) - else: - result = self._file.write(compressed_content.decode("utf-8")) - - self.bytes_total += result - self.bytes_since_last_reset += result - - return result - - def write_record_as_bytes(self, record: bytes): - result = self.write(record) - - self.records_total += 1 - self.records_since_last_reset += 1 - - return result - - def write_records_to_jsonl(self, records): - """Write records to a temporary file as JSONL.""" - if len(records) == 1: - jsonl_dump = orjson.dumps(records[0], option=orjson.OPT_APPEND_NEWLINE, default=str) - else: - jsonl_dump = b"\n".join(map(json_dumps_bytes, records)) - - result = self.write(jsonl_dump) - - self.records_total += len(records) - self.records_since_last_reset += len(records) - - return result - - def write_records_to_csv( - self, - records, - fieldnames: None | collections.abc.Sequence[str] = None, - extrasaction: typing.Literal["raise", "ignore"] = "ignore", - delimiter: str = ",", - quotechar: str = '"', - escapechar: str | None = "\\", - lineterminator: str = "\n", - quoting=csv.QUOTE_NONE, - ): - """Write records to a temporary file as CSV.""" - if len(records) == 0: - return - - if fieldnames is None: - fieldnames = list(records[0].keys()) - - writer = csv.DictWriter( - self, - fieldnames=fieldnames, - extrasaction=extrasaction, - delimiter=delimiter, - quotechar=quotechar, - escapechar=escapechar, - quoting=quoting, - lineterminator=lineterminator, - ) - writer.writerows(records) - - self.records_total += len(records) - self.records_since_last_reset += len(records) - - def write_records_to_tsv( - self, - records, - fieldnames: None | list[str] = None, - extrasaction: typing.Literal["raise", "ignore"] = "ignore", - quotechar: str = '"', - escapechar: str | None = "\\", - lineterminator: str = "\n", - quoting=csv.QUOTE_NONE, - ): - """Write records to a temporary file as TSV.""" - return self.write_records_to_csv( - records, - fieldnames=fieldnames, - extrasaction=extrasaction, - delimiter="\t", - quotechar=quotechar, - escapechar=escapechar, - quoting=quoting, - lineterminator=lineterminator, - ) - - def rewind(self): - """Rewind the file before reading it.""" - if self.compression == "brotli": - result = self._file.write(self.brotli_compressor.finish()) - - self.bytes_total += result - self.bytes_since_last_reset += result - - self._brotli_compressor = None - - self._file.seek(0) - - def reset(self): - """Reset underlying file by truncating it. - - Also resets the tracker attributes for bytes and records since last reset. - """ - self._file.seek(0) - self._file.truncate() - - self.bytes_since_last_reset = 0 - self.records_since_last_reset = 0 - - @dataclasses.dataclass class CreateBatchExportRunInputs: """Inputs to the create_export_run activity. diff --git a/posthog/temporal/batch_exports/bigquery_batch_export.py b/posthog/temporal/batch_exports/bigquery_batch_export.py index a0469de79bb9e..b754a7add16b4 100644 --- a/posthog/temporal/batch_exports/bigquery_batch_export.py +++ b/posthog/temporal/batch_exports/bigquery_batch_export.py @@ -15,7 +15,6 @@ from posthog.batch_exports.service import BatchExportField, BatchExportSchema, BigQueryBatchExportInputs from posthog.temporal.batch_exports.base import PostHogWorkflow from posthog.temporal.batch_exports.batch_exports import ( - BatchExportTemporaryFile, CreateBatchExportRunInputs, UpdateBatchExportRunStatusInputs, create_export_run, @@ -29,6 +28,9 @@ get_bytes_exported_metric, get_rows_exported_metric, ) +from posthog.temporal.batch_exports.temporary_file import ( + BatchExportTemporaryFile, +) from posthog.temporal.batch_exports.utils import peek_first_and_rewind from posthog.temporal.common.clickhouse import get_client from posthog.temporal.common.logger import bind_temporal_worker_logger diff --git a/posthog/temporal/batch_exports/http_batch_export.py b/posthog/temporal/batch_exports/http_batch_export.py index 8aca65c80ff38..2866d50c99876 100644 --- a/posthog/temporal/batch_exports/http_batch_export.py +++ b/posthog/temporal/batch_exports/http_batch_export.py @@ -13,7 +13,6 @@ from posthog.models import BatchExportRun from posthog.temporal.batch_exports.base import PostHogWorkflow from posthog.temporal.batch_exports.batch_exports import ( - BatchExportTemporaryFile, CreateBatchExportRunInputs, UpdateBatchExportRunStatusInputs, create_export_run, @@ -21,12 +20,15 @@ get_data_interval, get_rows_count, iter_records, - json_dumps_bytes, ) from posthog.temporal.batch_exports.metrics import ( get_bytes_exported_metric, get_rows_exported_metric, ) +from posthog.temporal.batch_exports.temporary_file import ( + BatchExportTemporaryFile, + json_dumps_bytes, +) from posthog.temporal.common.clickhouse import get_client from posthog.temporal.common.logger import bind_temporal_worker_logger diff --git a/posthog/temporal/batch_exports/postgres_batch_export.py b/posthog/temporal/batch_exports/postgres_batch_export.py index 5dbfc6faa4acf..98969ee78de79 100644 --- a/posthog/temporal/batch_exports/postgres_batch_export.py +++ b/posthog/temporal/batch_exports/postgres_batch_export.py @@ -17,7 +17,6 @@ from posthog.batch_exports.service import BatchExportField, BatchExportSchema, PostgresBatchExportInputs from posthog.temporal.batch_exports.base import PostHogWorkflow from posthog.temporal.batch_exports.batch_exports import ( - BatchExportTemporaryFile, CreateBatchExportRunInputs, UpdateBatchExportRunStatusInputs, create_export_run, @@ -31,6 +30,9 @@ get_bytes_exported_metric, get_rows_exported_metric, ) +from posthog.temporal.batch_exports.temporary_file import ( + BatchExportTemporaryFile, +) from posthog.temporal.batch_exports.utils import peek_first_and_rewind from posthog.temporal.common.clickhouse import get_client from posthog.temporal.common.logger import bind_temporal_worker_logger diff --git a/posthog/temporal/batch_exports/s3_batch_export.py b/posthog/temporal/batch_exports/s3_batch_export.py index 4d99cbeffd7c3..e83fe3f12915d 100644 --- a/posthog/temporal/batch_exports/s3_batch_export.py +++ b/posthog/temporal/batch_exports/s3_batch_export.py @@ -1,4 +1,5 @@ import asyncio +import collections.abc import contextlib import datetime as dt import io @@ -8,6 +9,8 @@ from dataclasses import dataclass import aioboto3 +import orjson +import pyarrow as pa from django.conf import settings from temporalio import activity, workflow from temporalio.common import RetryPolicy @@ -16,7 +19,6 @@ from posthog.batch_exports.service import BatchExportField, BatchExportSchema, S3BatchExportInputs from posthog.temporal.batch_exports.base import PostHogWorkflow from posthog.temporal.batch_exports.batch_exports import ( - BatchExportTemporaryFile, CreateBatchExportRunInputs, UpdateBatchExportRunStatusInputs, create_export_run, @@ -30,6 +32,15 @@ get_bytes_exported_metric, get_rows_exported_metric, ) +from posthog.temporal.batch_exports.temporary_file import ( + BatchExportTemporaryFile, + BatchExportWriter, + FlushCallable, + JSONLBatchExportWriter, + ParquetBatchExportWriter, + UnsupportedFileFormatError, +) +from posthog.temporal.batch_exports.utils import peek_first_and_rewind from posthog.temporal.common.clickhouse import get_client from posthog.temporal.common.logger import bind_temporal_worker_logger @@ -50,19 +61,31 @@ def get_allowed_template_variables(inputs) -> dict[str, str]: } +FILE_FORMAT_EXTENSIONS = { + "Parquet": "parquet", + "JSONLines": "jsonl", +} + +COMPRESSION_EXTENSIONS = { + "gzip": "gz", + "snappy": "sz", + "brotli": "br", + "ztsd": "zst", + "lz4": "lz4", +} + + def get_s3_key(inputs) -> str: """Return an S3 key given S3InsertInputs.""" template_variables = get_allowed_template_variables(inputs) key_prefix = inputs.prefix.format(**template_variables) + file_extension = FILE_FORMAT_EXTENSIONS[inputs.file_format] base_file_name = f"{inputs.data_interval_start}-{inputs.data_interval_end}" - match inputs.compression: - case "gzip": - file_name = base_file_name + ".jsonl.gz" - case "brotli": - file_name = base_file_name + ".jsonl.br" - case _: - file_name = base_file_name + ".jsonl" + if inputs.compression is not None: + file_name = base_file_name + f".{file_extension}.{COMPRESSION_EXTENSIONS[inputs.compression]}" + else: + file_name = base_file_name + f".{file_extension}" key = posixpath.join(key_prefix, file_name) @@ -311,6 +334,8 @@ class S3InsertInputs: kms_key_id: str | None = None batch_export_schema: BatchExportSchema | None = None endpoint_url: str | None = None + # TODO: In Python 3.11, this could be a enum.StrEnum. + file_format: str = "JSONLines" async def initialize_and_resume_multipart_upload(inputs: S3InsertInputs) -> tuple[S3MultiPartUpload, str]: @@ -451,7 +476,7 @@ async def insert_into_s3_activity(inputs: S3InsertInputs) -> int: last_uploaded_part_timestamp: str | None = None - async def worker_shutdown_handler(): + async def worker_shutdown_handler() -> None: """Handle the Worker shutting down by heart-beating our latest status.""" await activity.wait_for_worker_shutdown() logger.warn( @@ -466,50 +491,147 @@ async def worker_shutdown_handler(): asyncio.create_task(worker_shutdown_handler()) - record = None - async with s3_upload as s3_upload: - with BatchExportTemporaryFile(compression=inputs.compression) as local_results_file: + + async def flush_to_s3( + local_results_file, + records_since_last_flush: int, + bytes_since_last_flush: int, + last_inserted_at: dt.datetime, + last: bool, + ): + nonlocal last_uploaded_part_timestamp + + logger.debug( + "Uploading %s part %s containing %s records with size %s bytes", + "last " if last else "", + s3_upload.part_number + 1, + records_since_last_flush, + bytes_since_last_flush, + ) + + await s3_upload.upload_part(local_results_file) + rows_exported.add(records_since_last_flush) + bytes_exported.add(bytes_since_last_flush) + + last_uploaded_part_timestamp = str(last_inserted_at) + activity.heartbeat(last_uploaded_part_timestamp, s3_upload.to_state()) + + first_record_batch, record_iterator = peek_first_and_rewind(record_iterator) + first_record_batch = cast_record_batch_json_columns(first_record_batch) + column_names = first_record_batch.column_names + column_names.pop(column_names.index("_inserted_at")) + + schema = pa.schema( + # NOTE: For some reason, some batches set non-nullable fields as non-nullable, whereas other + # record batches have them as nullable. + # Until we figure it out, we set all fields to nullable. There are some fields we know + # are not nullable, but I'm opting for the more flexible option until we out why schemas differ + # between batches. + [field.with_nullable(True) for field in first_record_batch.select(column_names).schema] + ) + + writer = get_batch_export_writer( + inputs, + flush_callable=flush_to_s3, + max_bytes=settings.BATCH_EXPORT_S3_UPLOAD_CHUNK_SIZE_BYTES, + schema=schema, + ) + + async with writer.open_temporary_file(): rows_exported = get_rows_exported_metric() bytes_exported = get_bytes_exported_metric() - async def flush_to_s3(last_uploaded_part_timestamp: str, last=False): - logger.debug( - "Uploading %s part %s containing %s records with size %s bytes", - "last " if last else "", - s3_upload.part_number + 1, - local_results_file.records_since_last_reset, - local_results_file.bytes_since_last_reset, - ) + for record_batch in record_iterator: + record_batch = cast_record_batch_json_columns(record_batch) - await s3_upload.upload_part(local_results_file) - rows_exported.add(local_results_file.records_since_last_reset) - bytes_exported.add(local_results_file.bytes_since_last_reset) + await writer.write_record_batch(record_batch) - activity.heartbeat(last_uploaded_part_timestamp, s3_upload.to_state()) + await s3_upload.complete() - for record_batch in record_iterator: - for record in record_batch.to_pylist(): - for json_column in ("properties", "person_properties", "set", "set_once"): - if (json_str := record.get(json_column, None)) is not None: - record[json_column] = json.loads(json_str) + return writer.records_total - inserted_at = record.pop("_inserted_at") - local_results_file.write_records_to_jsonl([record]) +def get_batch_export_writer( + inputs: S3InsertInputs, flush_callable: FlushCallable, max_bytes: int, schema: pa.Schema | None = None +) -> BatchExportWriter: + """Return the `BatchExportWriter` corresponding to configured `file_format`. - if local_results_file.tell() > settings.BATCH_EXPORT_S3_UPLOAD_CHUNK_SIZE_BYTES: - last_uploaded_part_timestamp = str(inserted_at) - await flush_to_s3(last_uploaded_part_timestamp) - local_results_file.reset() + Raises: + UnsupportedFileFormatError: If no writer exists for given `file_format`. + """ + writer: BatchExportWriter - if local_results_file.tell() > 0 and record is not None: - last_uploaded_part_timestamp = str(inserted_at) - await flush_to_s3(last_uploaded_part_timestamp, last=True) + if inputs.file_format == "Parquet": + writer = ParquetBatchExportWriter( + max_bytes=max_bytes, + flush_callable=flush_callable, + compression=inputs.compression, + schema=schema, + ) + elif inputs.file_format == "JSONLines": + writer = JSONLBatchExportWriter( + max_bytes=settings.BATCH_EXPORT_S3_UPLOAD_CHUNK_SIZE_BYTES, + flush_callable=flush_callable, + compression=inputs.compression, + ) + else: + raise UnsupportedFileFormatError(inputs.file_format, "S3") - await s3_upload.complete() + return writer + + +def cast_record_batch_json_columns( + record_batch: pa.RecordBatch, + json_columns: collections.abc.Sequence = ("properties", "person_properties", "set", "set_once"), +) -> pa.RecordBatch: + """Cast json_columns in record_batch to JsonType. + + We return a new RecordBatch with any json_columns replaced by fields casted to JsonType. + Casting is not copying the underlying array buffers, so memory usage does not increase when creating + the new array or the new record batch. + """ + column_names = set(record_batch.column_names) + intersection = column_names & set(json_columns) + + casted_arrays = [] + for array in record_batch.select(intersection): + if pa.types.is_string(array.type): + casted_array = array.cast(JsonType()) + casted_arrays.append(casted_array) + + remaining_column_names = list(column_names - intersection) + return pa.RecordBatch.from_arrays( + record_batch.select(remaining_column_names).columns + casted_arrays, + names=remaining_column_names + list(intersection), + ) + + +class JsonScalar(pa.ExtensionScalar): + """Represents a JSON binary string.""" + + def as_py(self) -> dict | None: + if self.value: + return orjson.loads(self.value.as_py().encode("utf-8")) + else: + return None + + +class JsonType(pa.ExtensionType): + """Type for JSON binary strings.""" + + def __init__(self): + super().__init__(pa.string(), "json") + + def __arrow_ext_serialize__(self): + return b"" + + @classmethod + def __arrow_ext_deserialize__(self, storage_type, serialized): + return JsonType() - return local_results_file.records_total + def __arrow_ext_scalar_class__(self): + return JsonScalar @workflow.defn(name="s3-export") @@ -572,6 +694,7 @@ async def run(self, inputs: S3BatchExportInputs): encryption=inputs.encryption, kms_key_id=inputs.kms_key_id, batch_export_schema=inputs.batch_export_schema, + file_format=inputs.file_format, ) await execute_batch_export_insert_activity( diff --git a/posthog/temporal/batch_exports/snowflake_batch_export.py b/posthog/temporal/batch_exports/snowflake_batch_export.py index be94eca89a799..9053f3e1006ad 100644 --- a/posthog/temporal/batch_exports/snowflake_batch_export.py +++ b/posthog/temporal/batch_exports/snowflake_batch_export.py @@ -18,7 +18,6 @@ from posthog.batch_exports.service import BatchExportField, BatchExportSchema, SnowflakeBatchExportInputs from posthog.temporal.batch_exports.base import PostHogWorkflow from posthog.temporal.batch_exports.batch_exports import ( - BatchExportTemporaryFile, CreateBatchExportRunInputs, UpdateBatchExportRunStatusInputs, create_export_run, @@ -32,6 +31,9 @@ get_bytes_exported_metric, get_rows_exported_metric, ) +from posthog.temporal.batch_exports.temporary_file import ( + BatchExportTemporaryFile, +) from posthog.temporal.batch_exports.utils import peek_first_and_rewind from posthog.temporal.common.clickhouse import get_client from posthog.temporal.common.logger import bind_temporal_worker_logger diff --git a/posthog/temporal/batch_exports/temporary_file.py b/posthog/temporal/batch_exports/temporary_file.py new file mode 100644 index 0000000000000..f955f45553727 --- /dev/null +++ b/posthog/temporal/batch_exports/temporary_file.py @@ -0,0 +1,528 @@ +"""This module contains a temporary file to stage data in batch exports.""" +import abc +import collections.abc +import contextlib +import csv +import datetime as dt +import gzip +import tempfile +import typing + +import brotli +import orjson +import pyarrow as pa +import pyarrow.parquet as pq + + +def json_dumps_bytes(d) -> bytes: + return orjson.dumps(d, default=str) + + +class BatchExportTemporaryFile: + """A TemporaryFile used to as an intermediate step while exporting data. + + This class does not implement the file-like interface but rather passes any calls + to the underlying tempfile.NamedTemporaryFile. We do override 'write' methods + to allow tracking bytes and records. + """ + + def __init__( + self, + mode: str = "w+b", + buffering=-1, + compression: str | None = None, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + *, + errors: str | None = None, + ): + self._file = tempfile.NamedTemporaryFile( + mode=mode, + encoding=encoding, + newline=newline, + buffering=buffering, + suffix=suffix, + prefix=prefix, + dir=dir, + errors=errors, + ) + self.compression = compression + self.bytes_total = 0 + self.records_total = 0 + self.bytes_since_last_reset = 0 + self.records_since_last_reset = 0 + self._brotli_compressor = None + + def __getattr__(self, name): + """Pass get attr to underlying tempfile.NamedTemporaryFile.""" + return self._file.__getattr__(name) + + def __enter__(self): + """Context-manager protocol enter method.""" + self._file.__enter__() + return self + + def __exit__(self, exc, value, tb): + """Context-manager protocol exit method.""" + return self._file.__exit__(exc, value, tb) + + def __iter__(self): + yield from self._file + + @property + def brotli_compressor(self): + if self._brotli_compressor is None: + self._brotli_compressor = brotli.Compressor() + return self._brotli_compressor + + def finish_brotli_compressor(self): + """Flush remaining brotli bytes.""" + # TODO: Move compression out of `BatchExportTemporaryFile` to a standard class for all writers. + if self.compression != "brotli": + raise ValueError(f"Compression is '{self.compression}', not 'brotli'") + + result = self._file.write(self.brotli_compressor.finish()) + self.bytes_total += result + self.bytes_since_last_reset += result + self._brotli_compressor = None + + def compress(self, content: bytes | str) -> bytes: + if isinstance(content, str): + encoded = content.encode("utf-8") + else: + encoded = content + + match self.compression: + case "gzip": + return gzip.compress(encoded) + case "brotli": + self.brotli_compressor.process(encoded) + return self.brotli_compressor.flush() + case None: + return encoded + case _: + raise ValueError(f"Unsupported compression: '{self.compression}'") + + def write(self, content: bytes | str): + """Write bytes to underlying file keeping track of how many bytes were written.""" + compressed_content = self.compress(content) + + if "b" in self.mode: + result = self._file.write(compressed_content) + else: + result = self._file.write(compressed_content.decode("utf-8")) + + self.bytes_total += result + self.bytes_since_last_reset += result + + return result + + def write_record_as_bytes(self, record: bytes): + result = self.write(record) + + self.records_total += 1 + self.records_since_last_reset += 1 + + return result + + def write_records_to_jsonl(self, records): + """Write records to a temporary file as JSONL.""" + if len(records) == 1: + jsonl_dump = orjson.dumps(records[0], option=orjson.OPT_APPEND_NEWLINE, default=str) + else: + jsonl_dump = b"\n".join(map(json_dumps_bytes, records)) + + result = self.write(jsonl_dump) + + self.records_total += len(records) + self.records_since_last_reset += len(records) + + return result + + def write_records_to_csv( + self, + records, + fieldnames: None | collections.abc.Sequence[str] = None, + extrasaction: typing.Literal["raise", "ignore"] = "ignore", + delimiter: str = ",", + quotechar: str = '"', + escapechar: str | None = "\\", + lineterminator: str = "\n", + quoting=csv.QUOTE_NONE, + ): + """Write records to a temporary file as CSV.""" + if len(records) == 0: + return + + if fieldnames is None: + fieldnames = list(records[0].keys()) + + writer = csv.DictWriter( + self, + fieldnames=fieldnames, + extrasaction=extrasaction, + delimiter=delimiter, + quotechar=quotechar, + escapechar=escapechar, + quoting=quoting, + lineterminator=lineterminator, + ) + writer.writerows(records) + + self.records_total += len(records) + self.records_since_last_reset += len(records) + + def write_records_to_tsv( + self, + records, + fieldnames: None | list[str] = None, + extrasaction: typing.Literal["raise", "ignore"] = "ignore", + quotechar: str = '"', + escapechar: str | None = "\\", + lineterminator: str = "\n", + quoting=csv.QUOTE_NONE, + ): + """Write records to a temporary file as TSV.""" + return self.write_records_to_csv( + records, + fieldnames=fieldnames, + extrasaction=extrasaction, + delimiter="\t", + quotechar=quotechar, + escapechar=escapechar, + quoting=quoting, + lineterminator=lineterminator, + ) + + def rewind(self): + """Rewind the file before reading it.""" + self._file.seek(0) + + def reset(self): + """Reset underlying file by truncating it. + + Also resets the tracker attributes for bytes and records since last reset. + """ + self._file.seek(0) + self._file.truncate() + + self.bytes_since_last_reset = 0 + self.records_since_last_reset = 0 + + +LastInsertedAt = dt.datetime +IsLast = bool +RecordsSinceLastFlush = int +BytesSinceLastFlush = int +FlushCallable = collections.abc.Callable[ + [BatchExportTemporaryFile, RecordsSinceLastFlush, BytesSinceLastFlush, LastInsertedAt, IsLast], + collections.abc.Awaitable[None], +] + + +class UnsupportedFileFormatError(Exception): + """Raised when a writer for an unsupported file format is requested.""" + + def __init__(self, file_format: str, destination: str): + super().__init__(f"{file_format} is not a supported format for {destination} batch exports.") + + +class BatchExportWriter(abc.ABC): + """A temporary file writer to be used by batch export workflows. + + Subclasses should define `_write_record_batch` with the particular intricacies + of the format they are writing as. + + Actual writing calls are passed to the underlying `batch_export_file`. + + Attributes: + _batch_export_file: The temporary file we are writing to. + max_bytes: Flush the temporary file with the provided `flush_callable` + upon reaching or surpassing this threshold. Keep in mind we write on a RecordBatch + per RecordBatch basis, which means the threshold will be surpassed by at most the + size of a RecordBatch before a flush occurs. + flush_callable: A callback to flush the temporary file when `max_bytes` is reached. + The temporary file will be reset after calling `flush_callable`. When calling + `flush_callable` the following positional arguments will be passed: The temporary file + that must be flushed, the number of records since the last flush, the number of bytes + since the last flush, the latest recorded `_inserted_at`, and a `bool` indicating if + this is the last flush (when exiting the context manager). + file_kwargs: Optional keyword arguments passed when initializing `_batch_export_file`. + last_inserted_at: Latest `_inserted_at` written. This attribute leaks some implementation + details, as we are assuming assume `_inserted_at` is present, as it's added to all + batch export queries. + records_total: The total number of records (not RecordBatches!) written. + records_since_last_flush: The number of records written since last flush. + bytes_total: The total number of bytes written. + bytes_since_last_flush: The number of bytes written since last flush. + """ + + def __init__( + self, + flush_callable: FlushCallable, + max_bytes: int, + file_kwargs: collections.abc.Mapping[str, typing.Any] | None = None, + ): + self.flush_callable = flush_callable + self.max_bytes = max_bytes + self.file_kwargs: collections.abc.Mapping[str, typing.Any] = file_kwargs or {} + + self._batch_export_file: BatchExportTemporaryFile | None = None + self.reset_writer_tracking() + + def reset_writer_tracking(self): + """Reset this writer's tracking state.""" + self.last_inserted_at: dt.datetime | None = None + self.records_total = 0 + self.records_since_last_flush = 0 + self.bytes_total = 0 + self.bytes_since_last_flush = 0 + + @contextlib.asynccontextmanager + async def open_temporary_file(self): + """Explicitly open the temporary file this writer is writing to. + + The underlying `BatchExportTemporaryFile` is only accessible within this context manager. This helps + us separate the lifetime of the underlying temporary file from the writer: The writer may still be + accessed even after the temporary file is closed, while on the other hand we ensure the file and all + its data is flushed and not leaked outside the context. Any relevant tracking information is copied + to the writer. + """ + self.reset_writer_tracking() + + with BatchExportTemporaryFile(**self.file_kwargs) as temp_file: + self._batch_export_file = temp_file + + try: + yield + finally: + self.track_bytes_written(temp_file) + + if self.last_inserted_at is not None and self.bytes_since_last_flush > 0: + # `bytes_since_last_flush` should be 0 unless: + # 1. The last batch wasn't flushed as it didn't reach `max_bytes`. + # 2. The last batch was flushed but there was another write after the last call to + # `write_record_batch`. For example, footer bytes. + await self.flush(self.last_inserted_at, is_last=True) + + self._batch_export_file = None + + @property + def batch_export_file(self): + """Property for underlying temporary file. + + Raises: + ValueError: if attempting to access the temporary file before it has been opened. + """ + if self._batch_export_file is None: + raise ValueError("Batch export file is closed. Did you forget to call 'open_temporary_file'?") + return self._batch_export_file + + @abc.abstractmethod + def _write_record_batch(self, record_batch: pa.RecordBatch) -> None: + """Write a record batch to the underlying `BatchExportTemporaryFile`. + + Subclasses must override this to provide the actual implementation according to the supported + file format. + """ + pass + + def track_records_written(self, record_batch: pa.RecordBatch) -> None: + """Update this writer's state with the number of records in `record_batch`.""" + self.records_total += record_batch.num_rows + self.records_since_last_flush += record_batch.num_rows + + def track_bytes_written(self, batch_export_file: BatchExportTemporaryFile) -> None: + """Update this writer's state with the bytes in `batch_export_file`.""" + self.bytes_total = batch_export_file.bytes_total + self.bytes_since_last_flush = batch_export_file.bytes_since_last_reset + + async def write_record_batch(self, record_batch: pa.RecordBatch) -> None: + """Issue a record batch write tracking progress and flushing if required.""" + record_batch = record_batch.sort_by("_inserted_at") + last_inserted_at = record_batch.column("_inserted_at")[-1].as_py() + + column_names = record_batch.column_names + column_names.pop(column_names.index("_inserted_at")) + + self._write_record_batch(record_batch.select(column_names)) + + self.last_inserted_at = last_inserted_at + self.track_records_written(record_batch) + self.track_bytes_written(self.batch_export_file) + + if self.bytes_since_last_flush >= self.max_bytes: + await self.flush(last_inserted_at) + + async def flush(self, last_inserted_at: dt.datetime, is_last: bool = False) -> None: + """Call the provided `flush_callable` and reset underlying file. + + The underlying batch export temporary file will be reset after calling `flush_callable`. + """ + if is_last is True and self.batch_export_file.compression == "brotli": + self.batch_export_file.finish_brotli_compressor() + + self.batch_export_file.seek(0) + + await self.flush_callable( + self.batch_export_file, + self.records_since_last_flush, + self.bytes_since_last_flush, + last_inserted_at, + is_last, + ) + self.batch_export_file.reset() + + self.records_since_last_flush = 0 + self.bytes_since_last_flush = 0 + + +class JSONLBatchExportWriter(BatchExportWriter): + """A `BatchExportWriter` for JSONLines format. + + Attributes: + default: The default function to use to cast non-serializable Python objects to serializable objects. + By default, non-serializable objects will be cast to string via `str()`. + """ + + def __init__( + self, + max_bytes: int, + flush_callable: FlushCallable, + compression: None | str = None, + default: typing.Callable = str, + ): + super().__init__( + max_bytes=max_bytes, + flush_callable=flush_callable, + file_kwargs={"compression": compression}, + ) + + self.default = default + + def write(self, content: bytes) -> int: + """Write a single row of JSONL.""" + n = self.batch_export_file.write(orjson.dumps(content, default=str) + b"\n") + return n + + def _write_record_batch(self, record_batch: pa.RecordBatch) -> None: + """Write records to a temporary file as JSONL.""" + for record in record_batch.to_pylist(): + self.write(record) + + +class CSVBatchExportWriter(BatchExportWriter): + """A `BatchExportWriter` for CSV format.""" + + def __init__( + self, + max_bytes: int, + flush_callable: FlushCallable, + field_names: collections.abc.Sequence[str], + extras_action: typing.Literal["raise", "ignore"] = "ignore", + delimiter: str = ",", + quote_char: str = '"', + escape_char: str | None = "\\", + line_terminator: str = "\n", + quoting=csv.QUOTE_NONE, + compression: str | None = None, + ): + super().__init__( + max_bytes=max_bytes, + flush_callable=flush_callable, + file_kwargs={"compression": compression}, + ) + self.field_names = field_names + self.extras_action: typing.Literal["raise", "ignore"] = extras_action + self.delimiter = delimiter + self.quote_char = quote_char + self.escape_char = escape_char + self.line_terminator = line_terminator + self.quoting = quoting + + self._csv_writer: csv.DictWriter | None = None + + @property + def csv_writer(self) -> csv.DictWriter: + if self._csv_writer is None: + self._csv_writer = csv.DictWriter( + self.batch_export_file, + fieldnames=self.field_names, + extrasaction=self.extras_action, + delimiter=self.delimiter, + quotechar=self.quote_char, + escapechar=self.escape_char, + quoting=self.quoting, + lineterminator=self.line_terminator, + ) + + return self._csv_writer + + def _write_record_batch(self, record_batch: pa.RecordBatch) -> None: + """Write records to a temporary file as CSV.""" + self.csv_writer.writerows(record_batch.to_pylist()) + + +class ParquetBatchExportWriter(BatchExportWriter): + """A `BatchExportWriter` for Apache Parquet format. + + We utilize and wrap a `pyarrow.parquet.ParquetWriter` to do the actual writing. We default to their + defaults for most parameters; however this class could be extended with more attributes to pass along + to `pyarrow.parquet.ParquetWriter`. + + See the pyarrow docs for more details on what parameters can the writer be configured with: + https://arrow.apache.org/docs/python/generated/pyarrow.parquet.ParquetWriter.html + + In contrast to other writers, instead of us handling compression we let `pyarrow.parquet.ParquetWriter` + handle it, so `BatchExportTemporaryFile` is always initialized with `compression=None`. + + Attributes: + schema: The schema used by the Parquet file. Should match the schema of written RecordBatches. + compression: Compression codec passed to underlying `pyarrow.parquet.ParquetWriter`. + """ + + def __init__( + self, + max_bytes: int, + flush_callable: FlushCallable, + schema: pa.Schema, + compression: str | None = "snappy", + ): + super().__init__( + max_bytes=max_bytes, + flush_callable=flush_callable, + file_kwargs={"compression": None}, # ParquetWriter handles compression + ) + self.schema = schema + self.compression = compression + + self._parquet_writer: pq.ParquetWriter | None = None + + @property + def parquet_writer(self) -> pq.ParquetWriter: + if self._parquet_writer is None: + self._parquet_writer = pq.ParquetWriter( + self.batch_export_file, + schema=self.schema, + compression="none" if self.compression is None else self.compression, + ) + return self._parquet_writer + + @contextlib.asynccontextmanager + async def open_temporary_file(self): + """Ensure underlying Parquet writer is closed before flushing and closing temporary file.""" + async with super().open_temporary_file(): + try: + yield + finally: + if self._parquet_writer is not None: + self._parquet_writer.writer.close() + self._parquet_writer = None + + def _write_record_batch(self, record_batch: pa.RecordBatch) -> None: + """Write records to a temporary file as Parquet.""" + + self.parquet_writer.write_batch(record_batch.select(self.parquet_writer.schema.names)) diff --git a/posthog/temporal/tests/batch_exports/test_batch_exports.py b/posthog/temporal/tests/batch_exports/test_batch_exports.py index 0afbfcabb71cb..756c07e442e4f 100644 --- a/posthog/temporal/tests/batch_exports/test_batch_exports.py +++ b/posthog/temporal/tests/batch_exports/test_batch_exports.py @@ -1,6 +1,4 @@ -import csv import datetime as dt -import io import json import operator from random import randint @@ -9,11 +7,9 @@ from django.test import override_settings from posthog.temporal.batch_exports.batch_exports import ( - BatchExportTemporaryFile, get_data_interval, get_rows_count, iter_records, - json_dumps_bytes, ) from posthog.temporal.tests.utils.events import generate_test_events_in_clickhouse @@ -558,181 +554,3 @@ def test_get_data_interval(interval, data_interval_end, expected): """Test get_data_interval returns the expected data interval tuple.""" result = get_data_interval(interval, data_interval_end) assert result == expected - - -@pytest.mark.parametrize( - "to_write", - [ - (b"",), - (b"", b""), - (b"12345",), - (b"12345", b"12345"), - (b"abbcccddddeeeee",), - (b"abbcccddddeeeee", b"abbcccddddeeeee"), - ], -) -def test_batch_export_temporary_file_tracks_bytes(to_write): - """Test the bytes written by BatchExportTemporaryFile match expected.""" - with BatchExportTemporaryFile() as be_file: - for content in to_write: - be_file.write(content) - - assert be_file.bytes_total == sum(len(content) for content in to_write) - assert be_file.bytes_since_last_reset == sum(len(content) for content in to_write) - - be_file.reset() - - assert be_file.bytes_total == sum(len(content) for content in to_write) - assert be_file.bytes_since_last_reset == 0 - - -TEST_RECORDS = [ - [], - [ - {"id": "record-1", "property": "value", "property_int": 1}, - {"id": "record-2", "property": "another-value", "property_int": 2}, - { - "id": "record-3", - "property": {"id": "nested-record", "property": "nested-value"}, - "property_int": 3, - }, - ], -] - - -@pytest.mark.parametrize( - "records", - TEST_RECORDS, -) -def test_batch_export_temporary_file_write_records_to_jsonl(records): - """Test JSONL records written by BatchExportTemporaryFile match expected.""" - jsonl_dump = b"\n".join(map(json_dumps_bytes, records)) - - with BatchExportTemporaryFile() as be_file: - be_file.write_records_to_jsonl(records) - - assert be_file.bytes_total == len(jsonl_dump) - assert be_file.bytes_since_last_reset == len(jsonl_dump) - assert be_file.records_total == len(records) - assert be_file.records_since_last_reset == len(records) - - be_file.seek(0) - lines = be_file.readlines() - assert len(lines) == len(records) - - for line_index, jsonl_record in enumerate(lines): - json_loaded = json.loads(jsonl_record) - assert json_loaded == records[line_index] - - be_file.reset() - - assert be_file.bytes_total == len(jsonl_dump) - assert be_file.bytes_since_last_reset == 0 - assert be_file.records_total == len(records) - assert be_file.records_since_last_reset == 0 - - -@pytest.mark.parametrize( - "records", - TEST_RECORDS, -) -def test_batch_export_temporary_file_write_records_to_csv(records): - """Test CSV written by BatchExportTemporaryFile match expected.""" - in_memory_file_obj = io.StringIO() - writer = csv.DictWriter( - in_memory_file_obj, - fieldnames=records[0].keys() if len(records) > 0 else [], - delimiter=",", - quotechar='"', - escapechar="\\", - lineterminator="\n", - quoting=csv.QUOTE_NONE, - ) - writer.writerows(records) - - with BatchExportTemporaryFile(mode="w+") as be_file: - be_file.write_records_to_csv(records) - - assert be_file.bytes_total == in_memory_file_obj.tell() - assert be_file.bytes_since_last_reset == in_memory_file_obj.tell() - assert be_file.records_total == len(records) - assert be_file.records_since_last_reset == len(records) - - be_file.seek(0) - reader = csv.reader( - be_file._file, - delimiter=",", - quotechar='"', - escapechar="\\", - quoting=csv.QUOTE_NONE, - ) - - rows = [row for row in reader] - assert len(rows) == len(records) - - for row_index, csv_record in enumerate(rows): - for value_index, value in enumerate(records[row_index].values()): - # Everything returned by csv.reader is a str. - # This means type information is lost when writing to CSV - # but this just a limitation of the format. - assert csv_record[value_index] == str(value) - - be_file.reset() - - assert be_file.bytes_total == in_memory_file_obj.tell() - assert be_file.bytes_since_last_reset == 0 - assert be_file.records_total == len(records) - assert be_file.records_since_last_reset == 0 - - -@pytest.mark.parametrize( - "records", - TEST_RECORDS, -) -def test_batch_export_temporary_file_write_records_to_tsv(records): - """Test TSV written by BatchExportTemporaryFile match expected.""" - in_memory_file_obj = io.StringIO() - writer = csv.DictWriter( - in_memory_file_obj, - fieldnames=records[0].keys() if len(records) > 0 else [], - delimiter="\t", - quotechar='"', - escapechar="\\", - lineterminator="\n", - quoting=csv.QUOTE_NONE, - ) - writer.writerows(records) - - with BatchExportTemporaryFile(mode="w+") as be_file: - be_file.write_records_to_tsv(records) - - assert be_file.bytes_total == in_memory_file_obj.tell() - assert be_file.bytes_since_last_reset == in_memory_file_obj.tell() - assert be_file.records_total == len(records) - assert be_file.records_since_last_reset == len(records) - - be_file.seek(0) - reader = csv.reader( - be_file._file, - delimiter="\t", - quotechar='"', - escapechar="\\", - quoting=csv.QUOTE_NONE, - ) - - rows = [row for row in reader] - assert len(rows) == len(records) - - for row_index, csv_record in enumerate(rows): - for value_index, value in enumerate(records[row_index].values()): - # Everything returned by csv.reader is a str. - # This means type information is lost when writing to CSV - # but this just a limitation of the format. - assert csv_record[value_index] == str(value) - - be_file.reset() - - assert be_file.bytes_total == in_memory_file_obj.tell() - assert be_file.bytes_since_last_reset == 0 - assert be_file.records_total == len(records) - assert be_file.records_since_last_reset == 0 diff --git a/posthog/temporal/tests/batch_exports/test_s3_batch_export_workflow.py b/posthog/temporal/tests/batch_exports/test_s3_batch_export_workflow.py index e04e345d11245..e6583d049e2a8 100644 --- a/posthog/temporal/tests/batch_exports/test_s3_batch_export_workflow.py +++ b/posthog/temporal/tests/batch_exports/test_s3_batch_export_workflow.py @@ -10,10 +10,12 @@ import aioboto3 import botocore.exceptions import brotli +import pyarrow.parquet as pq import pytest import pytest_asyncio from django.conf import settings from django.test import override_settings +from pyarrow import fs from temporalio import activity from temporalio.client import WorkflowFailureError from temporalio.common import RetryPolicy @@ -27,6 +29,7 @@ update_export_run_status, ) from posthog.temporal.batch_exports.s3_batch_export import ( + FILE_FORMAT_EXTENSIONS, HeartbeatDetails, S3BatchExportInputs, S3BatchExportWorkflow, @@ -107,6 +110,15 @@ def s3_key_prefix(): return f"posthog-events-{str(uuid4())}" +@pytest.fixture +def file_format(request) -> str: + """S3 file format.""" + try: + return request.param + except AttributeError: + return f"JSONLines" + + async def delete_all_from_s3(minio_client, bucket_name: str, key_prefix: str): """Delete all objects in bucket_name under key_prefix.""" response = await minio_client.list_objects_v2(Bucket=bucket_name, Prefix=key_prefix) @@ -138,6 +150,61 @@ async def minio_client(bucket_name): await minio_client.delete_bucket(Bucket=bucket_name) +async def read_parquet_from_s3(bucket_name: str, key: str, json_columns) -> list: + async with aioboto3.Session().client("sts") as sts: + try: + await sts.get_caller_identity() + except botocore.exceptions.NoCredentialsError: + s3 = fs.S3FileSystem( + access_key="object_storage_root_user", + secret_key="object_storage_root_password", + endpoint_override=settings.OBJECT_STORAGE_ENDPOINT, + ) + + else: + if os.getenv("S3_TEST_BUCKET") is not None: + s3 = fs.S3FileSystem() + else: + s3 = fs.S3FileSystem( + access_key="object_storage_root_user", + secret_key="object_storage_root_password", + endpoint_override=settings.OBJECT_STORAGE_ENDPOINT, + ) + + table = pq.read_table(f"{bucket_name}/{key}", filesystem=s3) + + parquet_data = [] + for batch in table.to_batches(): + for record in batch.to_pylist(): + casted_record = {} + for k, v in record.items(): + if isinstance(v, dt.datetime): + # We read data from clickhouse as string, but parquet already casts them as dates. + # To facilitate comparison, we isoformat the dates. + casted_record[k] = v.isoformat() + elif k in json_columns and v is not None: + # Parquet doesn't have a variable map type, so JSON fields are just strings. + casted_record[k] = json.loads(v) + else: + casted_record[k] = v + parquet_data.append(casted_record) + + return parquet_data + + +def read_s3_data_as_json(data: bytes, compression: str | None) -> list: + match compression: + case "gzip": + data = gzip.decompress(data) + case "brotli": + data = brotli.decompress(data) + case _: + pass + + json_data = [json.loads(line) for line in data.decode("utf-8").split("\n") if line] + return json_data + + async def assert_clickhouse_records_in_s3( s3_compatible_client, clickhouse_client: ClickHouseClient, @@ -150,6 +217,7 @@ async def assert_clickhouse_records_in_s3( include_events: list[str] | None = None, batch_export_schema: BatchExportSchema | None = None, compression: str | None = None, + file_format: str = "JSONLines", ): """Assert ClickHouse records are written to JSON in key_prefix in S3 bucket_name. @@ -175,28 +243,24 @@ async def assert_clickhouse_records_in_s3( # Get the object. key = objects["Contents"][0].get("Key") assert key - s3_object = await s3_compatible_client.get_object(Bucket=bucket_name, Key=key) - data = await s3_object["Body"].read() - # Check that the data is correct. - match compression: - case "gzip": - data = gzip.decompress(data) - case "brotli": - data = brotli.decompress(data) - case _: - pass + json_columns = ("properties", "person_properties", "set", "set_once") - json_data = [json.loads(line) for line in data.decode("utf-8").split("\n") if line] - # Pull out the fields we inserted only + if file_format == "Parquet": + s3_data = await read_parquet_from_s3(bucket_name, key, json_columns) + + elif file_format == "JSONLines": + s3_object = await s3_compatible_client.get_object(Bucket=bucket_name, Key=key) + data = await s3_object["Body"].read() + s3_data = read_s3_data_as_json(data, compression) + else: + raise ValueError(f"Unsupported file format: {file_format}") if batch_export_schema is not None: schema_column_names = [field["alias"] for field in batch_export_schema["fields"]] else: schema_column_names = [field["alias"] for field in s3_default_fields()] - json_columns = ("properties", "person_properties", "set", "set_once") - expected_records = [] for record_batch in iter_records( client=clickhouse_client, @@ -225,9 +289,9 @@ async def assert_clickhouse_records_in_s3( expected_records.append(expected_record) - assert len(json_data) == len(expected_records) - assert json_data[0] == expected_records[0] - assert json_data == expected_records + assert len(s3_data) == len(expected_records) + assert s3_data[0] == expected_records[0] + assert s3_data == expected_records TEST_S3_SCHEMAS: list[BatchExportSchema | None] = [ @@ -255,6 +319,7 @@ async def assert_clickhouse_records_in_s3( @pytest.mark.parametrize("compression", [None, "gzip", "brotli"], indirect=True) @pytest.mark.parametrize("exclude_events", [None, ["test-exclude"]], indirect=True) @pytest.mark.parametrize("batch_export_schema", TEST_S3_SCHEMAS) +@pytest.mark.parametrize("file_format", FILE_FORMAT_EXTENSIONS.keys()) async def test_insert_into_s3_activity_puts_data_into_s3( clickhouse_client, bucket_name, @@ -262,6 +327,7 @@ async def test_insert_into_s3_activity_puts_data_into_s3( activity_environment, compression, exclude_events, + file_format, batch_export_schema: BatchExportSchema | None, ): """Test that the insert_into_s3_activity function ends up with data into S3. @@ -339,12 +405,15 @@ async def test_insert_into_s3_activity_puts_data_into_s3( compression=compression, exclude_events=exclude_events, batch_export_schema=batch_export_schema, + file_format=file_format, ) with override_settings( BATCH_EXPORT_S3_UPLOAD_CHUNK_SIZE_BYTES=5 * 1024**2 ): # 5MB, the minimum for Multipart uploads - await activity_environment.run(insert_into_s3_activity, insert_inputs) + records_total = await activity_environment.run(insert_into_s3_activity, insert_inputs) + + assert records_total == 10005 await assert_clickhouse_records_in_s3( s3_compatible_client=minio_client, @@ -358,6 +427,7 @@ async def test_insert_into_s3_activity_puts_data_into_s3( exclude_events=exclude_events, include_events=None, compression=compression, + file_format=file_format, ) @@ -371,6 +441,7 @@ async def s3_batch_export( exclude_events, temporal_client, encryption, + file_format, ): destination_data = { "type": "S3", @@ -385,6 +456,7 @@ async def s3_batch_export( "exclude_events": exclude_events, "encryption": encryption, "kms_key_id": os.getenv("S3_TEST_KMS_KEY_ID") if encryption == "aws:kms" else None, + "file_format": file_format, }, } @@ -410,6 +482,7 @@ async def s3_batch_export( @pytest.mark.parametrize("compression", [None, "gzip", "brotli"], indirect=True) @pytest.mark.parametrize("exclude_events", [None, ["test-exclude"]], indirect=True) @pytest.mark.parametrize("batch_export_schema", TEST_S3_SCHEMAS) +@pytest.mark.parametrize("file_format", FILE_FORMAT_EXTENSIONS.keys(), indirect=True) async def test_s3_export_workflow_with_minio_bucket( clickhouse_client, minio_client, @@ -421,6 +494,7 @@ async def test_s3_export_workflow_with_minio_bucket( exclude_events, s3_key_prefix, batch_export_schema, + file_format, ): """Test S3BatchExport Workflow end-to-end by using a local MinIO bucket instead of S3. @@ -508,6 +582,7 @@ async def test_s3_export_workflow_with_minio_bucket( batch_export_schema=batch_export_schema, exclude_events=exclude_events, compression=compression, + file_format=file_format, ) @@ -537,6 +612,7 @@ async def s3_client(bucket_name, s3_key_prefix): @pytest.mark.parametrize("encryption", [None, "AES256", "aws:kms"], indirect=True) @pytest.mark.parametrize("bucket_name", [os.getenv("S3_TEST_BUCKET")], indirect=True) @pytest.mark.parametrize("batch_export_schema", TEST_S3_SCHEMAS) +@pytest.mark.parametrize("file_format", FILE_FORMAT_EXTENSIONS.keys(), indirect=True) async def test_s3_export_workflow_with_s3_bucket( s3_client, clickhouse_client, @@ -549,6 +625,7 @@ async def test_s3_export_workflow_with_s3_bucket( exclude_events, ateam, batch_export_schema, + file_format, ): """Test S3 Export Workflow end-to-end by using an S3 bucket. @@ -646,6 +723,7 @@ async def test_s3_export_workflow_with_s3_bucket( exclude_events=exclude_events, include_events=None, compression=compression, + file_format=file_format, ) @@ -1206,6 +1284,49 @@ async def never_finish_activity(_: S3InsertInputs) -> str: ), "nested/prefix/2023-01-01 00:00:00-2023-01-01 01:00:00.jsonl.br", ), + ( + S3InsertInputs( + prefix="/nested/prefix/", + data_interval_start="2023-01-01 00:00:00", + data_interval_end="2023-01-01 01:00:00", + file_format="Parquet", + compression="snappy", + **base_inputs, # type: ignore + ), + "nested/prefix/2023-01-01 00:00:00-2023-01-01 01:00:00.parquet.sz", + ), + ( + S3InsertInputs( + prefix="/nested/prefix/", + data_interval_start="2023-01-01 00:00:00", + data_interval_end="2023-01-01 01:00:00", + file_format="Parquet", + **base_inputs, # type: ignore + ), + "nested/prefix/2023-01-01 00:00:00-2023-01-01 01:00:00.parquet", + ), + ( + S3InsertInputs( + prefix="/nested/prefix/", + data_interval_start="2023-01-01 00:00:00", + data_interval_end="2023-01-01 01:00:00", + compression="gzip", + file_format="Parquet", + **base_inputs, # type: ignore + ), + "nested/prefix/2023-01-01 00:00:00-2023-01-01 01:00:00.parquet.gz", + ), + ( + S3InsertInputs( + prefix="/nested/prefix/", + data_interval_start="2023-01-01 00:00:00", + data_interval_end="2023-01-01 01:00:00", + compression="brotli", + file_format="Parquet", + **base_inputs, # type: ignore + ), + "nested/prefix/2023-01-01 00:00:00-2023-01-01 01:00:00.parquet.br", + ), ], ) def test_get_s3_key(inputs, expected): @@ -1271,7 +1392,7 @@ def assert_heartbeat_details(*details): endpoint_url=settings.OBJECT_STORAGE_ENDPOINT, ) - with override_settings(BATCH_EXPORT_S3_UPLOAD_CHUNK_SIZE_BYTES=5 * 1024**2): + with override_settings(BATCH_EXPORT_S3_UPLOAD_CHUNK_SIZE_BYTES=1, CLICKHOUSE_MAX_BLOCK_SIZE_DEFAULT=1): await activity_environment.run(insert_into_s3_activity, insert_inputs) # This checks that the assert_heartbeat_details function was actually called. diff --git a/posthog/temporal/tests/batch_exports/test_temporary_file.py b/posthog/temporal/tests/batch_exports/test_temporary_file.py new file mode 100644 index 0000000000000..4fd7e69c0c12f --- /dev/null +++ b/posthog/temporal/tests/batch_exports/test_temporary_file.py @@ -0,0 +1,389 @@ +import csv +import datetime as dt +import io +import json + +import pyarrow as pa +import pyarrow.parquet as pq +import pytest + +from posthog.temporal.batch_exports.temporary_file import ( + BatchExportTemporaryFile, + CSVBatchExportWriter, + JSONLBatchExportWriter, + ParquetBatchExportWriter, + json_dumps_bytes, +) + + +@pytest.mark.parametrize( + "to_write", + [ + (b"",), + (b"", b""), + (b"12345",), + (b"12345", b"12345"), + (b"abbcccddddeeeee",), + (b"abbcccddddeeeee", b"abbcccddddeeeee"), + ], +) +def test_batch_export_temporary_file_tracks_bytes(to_write): + """Test the bytes written by BatchExportTemporaryFile match expected.""" + with BatchExportTemporaryFile() as be_file: + for content in to_write: + be_file.write(content) + + assert be_file.bytes_total == sum(len(content) for content in to_write) + assert be_file.bytes_since_last_reset == sum(len(content) for content in to_write) + + be_file.reset() + + assert be_file.bytes_total == sum(len(content) for content in to_write) + assert be_file.bytes_since_last_reset == 0 + + +TEST_RECORDS = [ + [], + [ + {"id": "record-1", "property": "value", "property_int": 1}, + {"id": "record-2", "property": "another-value", "property_int": 2}, + { + "id": "record-3", + "property": {"id": "nested-record", "property": "nested-value"}, + "property_int": 3, + }, + ], +] + + +@pytest.mark.parametrize( + "records", + TEST_RECORDS, +) +def test_batch_export_temporary_file_write_records_to_jsonl(records): + """Test JSONL records written by BatchExportTemporaryFile match expected.""" + jsonl_dump = b"\n".join(map(json_dumps_bytes, records)) + + with BatchExportTemporaryFile() as be_file: + be_file.write_records_to_jsonl(records) + + assert be_file.bytes_total == len(jsonl_dump) + assert be_file.bytes_since_last_reset == len(jsonl_dump) + assert be_file.records_total == len(records) + assert be_file.records_since_last_reset == len(records) + + be_file.seek(0) + lines = be_file.readlines() + assert len(lines) == len(records) + + for line_index, jsonl_record in enumerate(lines): + json_loaded = json.loads(jsonl_record) + assert json_loaded == records[line_index] + + be_file.reset() + + assert be_file.bytes_total == len(jsonl_dump) + assert be_file.bytes_since_last_reset == 0 + assert be_file.records_total == len(records) + assert be_file.records_since_last_reset == 0 + + +@pytest.mark.parametrize( + "records", + TEST_RECORDS, +) +def test_batch_export_temporary_file_write_records_to_csv(records): + """Test CSV written by BatchExportTemporaryFile match expected.""" + in_memory_file_obj = io.StringIO() + writer = csv.DictWriter( + in_memory_file_obj, + fieldnames=records[0].keys() if len(records) > 0 else [], + delimiter=",", + quotechar='"', + escapechar="\\", + lineterminator="\n", + quoting=csv.QUOTE_NONE, + ) + writer.writerows(records) + + with BatchExportTemporaryFile(mode="w+") as be_file: + be_file.write_records_to_csv(records) + + assert be_file.bytes_total == in_memory_file_obj.tell() + assert be_file.bytes_since_last_reset == in_memory_file_obj.tell() + assert be_file.records_total == len(records) + assert be_file.records_since_last_reset == len(records) + + be_file.seek(0) + reader = csv.reader( + be_file._file, + delimiter=",", + quotechar='"', + escapechar="\\", + quoting=csv.QUOTE_NONE, + ) + + rows = [row for row in reader] + assert len(rows) == len(records) + + for row_index, csv_record in enumerate(rows): + for value_index, value in enumerate(records[row_index].values()): + # Everything returned by csv.reader is a str. + # This means type information is lost when writing to CSV + # but this just a limitation of the format. + assert csv_record[value_index] == str(value) + + be_file.reset() + + assert be_file.bytes_total == in_memory_file_obj.tell() + assert be_file.bytes_since_last_reset == 0 + assert be_file.records_total == len(records) + assert be_file.records_since_last_reset == 0 + + +@pytest.mark.parametrize( + "records", + TEST_RECORDS, +) +def test_batch_export_temporary_file_write_records_to_tsv(records): + """Test TSV written by BatchExportTemporaryFile match expected.""" + in_memory_file_obj = io.StringIO() + writer = csv.DictWriter( + in_memory_file_obj, + fieldnames=records[0].keys() if len(records) > 0 else [], + delimiter="\t", + quotechar='"', + escapechar="\\", + lineterminator="\n", + quoting=csv.QUOTE_NONE, + ) + writer.writerows(records) + + with BatchExportTemporaryFile(mode="w+") as be_file: + be_file.write_records_to_tsv(records) + + assert be_file.bytes_total == in_memory_file_obj.tell() + assert be_file.bytes_since_last_reset == in_memory_file_obj.tell() + assert be_file.records_total == len(records) + assert be_file.records_since_last_reset == len(records) + + be_file.seek(0) + reader = csv.reader( + be_file._file, + delimiter="\t", + quotechar='"', + escapechar="\\", + quoting=csv.QUOTE_NONE, + ) + + rows = [row for row in reader] + assert len(rows) == len(records) + + for row_index, csv_record in enumerate(rows): + for value_index, value in enumerate(records[row_index].values()): + # Everything returned by csv.reader is a str. + # This means type information is lost when writing to CSV + # but this just a limitation of the format. + assert csv_record[value_index] == str(value) + + be_file.reset() + + assert be_file.bytes_total == in_memory_file_obj.tell() + assert be_file.bytes_since_last_reset == 0 + assert be_file.records_total == len(records) + assert be_file.records_since_last_reset == 0 + + +TEST_RECORD_BATCHES = [ + pa.RecordBatch.from_pydict( + { + "event": pa.array(["test-event-0", "test-event-1", "test-event-2"]), + "properties": pa.array(['{"prop_0": 1, "prop_1": 2}', "{}", "null"]), + "_inserted_at": pa.array([0, 1, 2]), + } + ) +] + + +@pytest.mark.parametrize( + "record_batch", + TEST_RECORD_BATCHES, +) +@pytest.mark.asyncio +async def test_jsonl_writer_writes_record_batches(record_batch): + """Test record batches are written as valid JSONL.""" + in_memory_file_obj = io.BytesIO() + inserted_ats_seen = [] + + async def store_in_memory_on_flush( + batch_export_file, records_since_last_flush, bytes_since_last_flush, last_inserted_at, is_last + ): + in_memory_file_obj.write(batch_export_file.read()) + inserted_ats_seen.append(last_inserted_at) + + writer = JSONLBatchExportWriter(max_bytes=1, flush_callable=store_in_memory_on_flush) + + record_batch = record_batch.sort_by("_inserted_at") + async with writer.open_temporary_file(): + await writer.write_record_batch(record_batch) + + lines = in_memory_file_obj.readlines() + for index, line in enumerate(lines): + written_jsonl = json.loads(line) + + single_record_batch = record_batch.slice(offset=index, length=1) + expected_jsonl = single_record_batch.to_pylist()[0] + + assert "_inserted_at" not in written_jsonl + assert written_jsonl == expected_jsonl + + assert inserted_ats_seen == [record_batch.column("_inserted_at")[-1].as_py()] + + +@pytest.mark.parametrize( + "record_batch", + TEST_RECORD_BATCHES, +) +@pytest.mark.asyncio +async def test_csv_writer_writes_record_batches(record_batch): + """Test record batches are written as valid CSV.""" + in_memory_file_obj = io.StringIO() + inserted_ats_seen = [] + + async def store_in_memory_on_flush( + batch_export_file, records_since_last_flush, bytes_since_last_flush, last_inserted_at, is_last + ): + in_memory_file_obj.write(batch_export_file.read().decode("utf-8")) + inserted_ats_seen.append(last_inserted_at) + + schema_columns = [column_name for column_name in record_batch.column_names if column_name != "_inserted_at"] + writer = CSVBatchExportWriter(max_bytes=1, field_names=schema_columns, flush_callable=store_in_memory_on_flush) + + record_batch = record_batch.sort_by("_inserted_at") + async with writer.open_temporary_file(): + await writer.write_record_batch(record_batch) + + reader = csv.reader( + in_memory_file_obj, + delimiter=",", + quotechar='"', + escapechar="\\", + quoting=csv.QUOTE_NONE, + ) + for index, written_csv_row in enumerate(reader): + single_record_batch = record_batch.slice(offset=index, length=1) + expected_csv = single_record_batch.to_pylist()[0] + + assert "_inserted_at" not in written_csv_row + assert written_csv_row == expected_csv + + assert inserted_ats_seen == [record_batch.column("_inserted_at")[-1].as_py()] + + +@pytest.mark.parametrize( + "record_batch", + TEST_RECORD_BATCHES, +) +@pytest.mark.asyncio +async def test_parquet_writer_writes_record_batches(record_batch): + """Test record batches are written as valid Parquet.""" + in_memory_file_obj = io.BytesIO() + inserted_ats_seen = [] + + async def store_in_memory_on_flush( + batch_export_file, records_since_last_flush, bytes_since_last_flush, last_inserted_at, is_last + ): + in_memory_file_obj.write(batch_export_file.read()) + inserted_ats_seen.append(last_inserted_at) + + schema_columns = [column_name for column_name in record_batch.column_names if column_name != "_inserted_at"] + + writer = ParquetBatchExportWriter( + max_bytes=1, + flush_callable=store_in_memory_on_flush, + schema=record_batch.select(schema_columns).schema, + ) + + record_batch = record_batch.sort_by("_inserted_at") + async with writer.open_temporary_file(): + await writer.write_record_batch(record_batch) + + written_parquet = pq.read_table(in_memory_file_obj) + + for index, written_row_as_dict in enumerate(written_parquet.to_pylist()): + single_record_batch = record_batch.slice(offset=index, length=1) + expected_row_as_dict = single_record_batch.select(schema_columns).to_pylist()[0] + + assert "_inserted_at" not in written_row_as_dict + assert written_row_as_dict == expected_row_as_dict + + # NOTE: Parquet gets flushed twice due to the extra flush at the end for footer bytes, so our mock function + # will see this value twice. + assert inserted_ats_seen == [ + record_batch.column("_inserted_at")[-1].as_py(), + record_batch.column("_inserted_at")[-1].as_py(), + ] + + +@pytest.mark.parametrize( + "record_batch", + TEST_RECORD_BATCHES, +) +@pytest.mark.asyncio +async def test_writing_out_of_scope_of_temporary_file_raises(record_batch): + """Test attempting a write out of temporary file scope raises a `ValueError`.""" + + async def do_nothing(*args, **kwargs): + pass + + schema_columns = [column_name for column_name in record_batch.column_names if column_name != "_inserted_at"] + writer = ParquetBatchExportWriter( + max_bytes=10, + flush_callable=do_nothing, + schema=record_batch.select(schema_columns).schema, + ) + + async with writer.open_temporary_file(): + pass + + with pytest.raises(ValueError, match="Batch export file is closed"): + await writer.write_record_batch(record_batch) + + +@pytest.mark.parametrize( + "record_batch", + TEST_RECORD_BATCHES, +) +@pytest.mark.asyncio +async def test_flushing_parquet_writer_resets_underlying_file(record_batch): + """Test flushing a writer resets underlying file.""" + flush_counter = 0 + + async def track_flushes(*args, **kwargs): + nonlocal flush_counter + flush_counter += 1 + + schema_columns = [column_name for column_name in record_batch.column_names if column_name != "_inserted_at"] + writer = ParquetBatchExportWriter( + max_bytes=10000000, + flush_callable=track_flushes, + schema=record_batch.select(schema_columns).schema, + ) + + async with writer.open_temporary_file(): + await writer.write_record_batch(record_batch) + + assert writer.batch_export_file.tell() > 0 + assert writer.bytes_since_last_flush > 0 + assert writer.bytes_since_last_flush == writer.batch_export_file.bytes_since_last_reset + assert writer.records_since_last_flush == record_batch.num_rows + + await writer.flush(dt.datetime.now()) + + assert flush_counter == 1 + assert writer.batch_export_file.tell() == 0 + assert writer.bytes_since_last_flush == 0 + assert writer.bytes_since_last_flush == writer.batch_export_file.bytes_since_last_reset + assert writer.records_since_last_flush == 0 + + assert flush_counter == 2 From fcc192e83db4273e0904993922cba9a62c2d3752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Fri, 22 Mar 2024 14:51:00 +0100 Subject: [PATCH 11/16] feat: Frontend support for file_format in S3 batch export (#21076) * refactor: Support for multiple file formats in batch exports * refactor: Prefer composition over inheritance * refactor: More clearly separate writer from temporary file We now should be more explicit about what is the context in which the batch export temporary file is alive. The writer outlives this context, so it can be used by callers to, for example, check how many records were written. * test: More parquet testing * refactor: Move temporary file to new module * feat: Frontend support for file_format * fix: Remove redefinition caused by rebase --- .../src/scenes/batch_exports/BatchExportEditForm.tsx | 9 +++++++++ .../src/scenes/batch_exports/BatchExports.stories.tsx | 1 + .../src/scenes/batch_exports/batchExportEditLogic.ts | 1 + frontend/src/types.ts | 1 + 4 files changed, 12 insertions(+) diff --git a/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx b/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx index b015659cfaef1..a2a9f9968f82c 100644 --- a/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx +++ b/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx @@ -242,6 +242,15 @@ export function BatchExportsEditFields({ ]} /> + + + +
diff --git a/frontend/src/scenes/batch_exports/BatchExports.stories.tsx b/frontend/src/scenes/batch_exports/BatchExports.stories.tsx index 0dd616c44982a..dbd6779cb208d 100644 --- a/frontend/src/scenes/batch_exports/BatchExports.stories.tsx +++ b/frontend/src/scenes/batch_exports/BatchExports.stories.tsx @@ -42,6 +42,7 @@ export default { include_events: [], encryption: null, kms_key_id: null, + file_format: 'JSONLines', }, }, start_at: null, diff --git a/frontend/src/scenes/batch_exports/batchExportEditLogic.ts b/frontend/src/scenes/batch_exports/batchExportEditLogic.ts index bc86d1618fe4f..30c123256d81a 100644 --- a/frontend/src/scenes/batch_exports/batchExportEditLogic.ts +++ b/frontend/src/scenes/batch_exports/batchExportEditLogic.ts @@ -90,6 +90,7 @@ export const batchExportFormFields = ( aws_secret_access_key: isNew ? (!config.aws_secret_access_key ? 'This field is required' : '') : '', compression: '', encryption: '', + file_format: isNew ? (!config.file_format ? 'This field is required' : '') : '', kms_key_id: !config.kms_key_id && config.encryption == 'aws:kms' ? 'This field is required' : '', exclude_events: '', include_events: '', diff --git a/frontend/src/types.ts b/frontend/src/types.ts index be96494253ae8..58f54b786a7df 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -3597,6 +3597,7 @@ export type BatchExportDestinationS3 = { encryption: string | null kms_key_id: string | null endpoint_url: string | null + file_format: string } } From 17c5876ef880f3771af2f4a08f88b01e9bb752a9 Mon Sep 17 00:00:00 2001 From: Xavier Vello Date: Fri, 22 Mar 2024 15:05:54 +0100 Subject: [PATCH 12/16] chore(blobby): raise overflow trigger again (#21104) --- plugin-server/src/config/config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-server/src/config/config.ts b/plugin-server/src/config/config.ts index dcaebe4c1097a..def72eea474bb 100644 --- a/plugin-server/src/config/config.ts +++ b/plugin-server/src/config/config.ts @@ -164,8 +164,8 @@ export function getDefaultConfig(): PluginsServerConfig { SESSION_RECORDING_KAFKA_DEBUG: undefined, SESSION_RECORDING_MAX_PARALLEL_FLUSHES: 10, SESSION_RECORDING_OVERFLOW_ENABLED: false, - SESSION_RECORDING_OVERFLOW_BUCKET_REPLENISH_RATE: 2_000_000, // 2MB/second uncompressed, sustained - SESSION_RECORDING_OVERFLOW_BUCKET_CAPACITY: 100_000_000, // 100MB burst + SESSION_RECORDING_OVERFLOW_BUCKET_REPLENISH_RATE: 5_000_000, // 5MB/second uncompressed, sustained + SESSION_RECORDING_OVERFLOW_BUCKET_CAPACITY: 200_000_000, // 200MB burst } } From e5bec128fc75cf42ab61bfa274fa856b6ef52556 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Fri, 22 Mar 2024 17:48:43 +0000 Subject: [PATCH 13/16] fix: invalid text node should not render (#21093) --- .../increment-with-child-duplication.json | 7 + .../__snapshots__/transform.test.ts.snap | 162 ++++++++++++++++++ ee/frontend/mobile-replay/transform.test.ts | 37 ++++ .../mobile-replay/transformer/transformers.ts | 26 ++- 4 files changed, 223 insertions(+), 9 deletions(-) diff --git a/ee/frontend/mobile-replay/__mocks__/increment-with-child-duplication.json b/ee/frontend/mobile-replay/__mocks__/increment-with-child-duplication.json index c17efc6d9e246..7ffc2e5f38e5c 100644 --- a/ee/frontend/mobile-replay/__mocks__/increment-with-child-duplication.json +++ b/ee/frontend/mobile-replay/__mocks__/increment-with-child-duplication.json @@ -191,6 +191,13 @@ "x": 66, "y": 556 } + }, + { + "parentId": 209272202, + "wireframe": { + "id": 52129787123, + "type": "text" + } } ], "removes": [ diff --git a/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap b/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap index a421f7ff220bf..bbde91f8defc6 100644 --- a/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap +++ b/ee/frontend/mobile-replay/__snapshots__/transform.test.ts.snap @@ -160,6 +160,147 @@ exports[`replay/transform transform can convert images 1`] = ` ] `; +exports[`replay/transform transform can convert invalid text wireframe 1`] = ` +[ + { + "data": { + "height": 600, + "href": "", + "width": 300, + }, + "timestamp": 1, + "type": 4, + }, + { + "data": { + "initialOffset": { + "left": 0, + "top": 0, + }, + "node": { + "childNodes": [ + { + "id": 2, + "name": "html", + "publicId": "", + "systemId": "", + "type": 1, + }, + { + "attributes": { + "data-rrweb-id": 3, + "style": "height: 100vh; width: 100vw;", + }, + "childNodes": [ + { + "attributes": { + "data-rrweb-id": 4, + }, + "childNodes": [ + { + "attributes": { + "type": "text/css", + }, + "childNodes": [ + { + "id": 102, + "textContent": " + body { + margin: unset; + } + input, button, select, textarea { + font: inherit; + margin: 0; + padding: 0; + border: 0; + outline: 0; + background: transparent; + padding-block: 0 !important; + } + .input:focus { + outline: none; + } + img { + border-style: none; + } + ", + "type": 3, + }, + ], + "id": 101, + "tagName": "style", + "type": 2, + }, + ], + "id": 4, + "tagName": "head", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 5, + "style": "height: 100vh; width: 100vw;", + }, + "childNodes": [ + { + "attributes": { + "data-rrweb-id": 12345, + "style": "border-width: 4px;border-radius: 10px;border-color: #ee3ee4;border-style: solid;color: #ee3ee4;width: 100px;height: 30px;position: fixed;left: 11px;top: 12px;overflow:hidden;white-space:normal;", + }, + "childNodes": [], + "id": 12345, + "tagName": "div", + "type": 2, + }, + { + "attributes": { + "data-render-reason": "a fixed placeholder to contain the keyboard in the correct stacking position", + "data-rrweb-id": 9, + }, + "childNodes": [], + "id": 9, + "tagName": "div", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 7, + }, + "childNodes": [], + "id": 7, + "tagName": "div", + "type": 2, + }, + { + "attributes": { + "data-rrweb-id": 11, + }, + "childNodes": [], + "id": 11, + "tagName": "div", + "type": 2, + }, + ], + "id": 5, + "tagName": "body", + "type": 2, + }, + ], + "id": 3, + "tagName": "html", + "type": 2, + }, + ], + "id": 1, + "type": 0, + }, + }, + "timestamp": 1, + "type": 2, + }, +] +`; + exports[`replay/transform transform can convert navigation bar 1`] = ` [ { @@ -1453,6 +1594,20 @@ exports[`replay/transform transform incremental mutations de-duplicate the tree }, "parentId": 52129787, }, + { + "nextId": null, + "node": { + "attributes": { + "data-rrweb-id": 52129787123, + "style": "position: fixed;left: 0px;top: 0px;overflow:hidden;white-space:normal;", + }, + "childNodes": [], + "id": 52129787123, + "tagName": "div", + "type": 2, + }, + "parentId": 209272202, + }, ], "attributes": [], "removes": [ @@ -1689,6 +1844,13 @@ AAAAAAAAAAAAAAAAAAAAAAAAgCN/AW0xMqHnNQceAAAAAElFTkSuQmCC "y": 556, }, }, + { + "parentId": 209272202, + "wireframe": { + "id": 52129787123, + "type": "text", + }, + }, ], "removes": [ { diff --git a/ee/frontend/mobile-replay/transform.test.ts b/ee/frontend/mobile-replay/transform.test.ts index 788bb65655d3d..92384e48b2986 100644 --- a/ee/frontend/mobile-replay/transform.test.ts +++ b/ee/frontend/mobile-replay/transform.test.ts @@ -480,6 +480,43 @@ describe('replay/transform', () => { expect(converted).toMatchSnapshot() }) + test('can convert invalid text wireframe', () => { + const converted = posthogEEModule.mobileReplay?.transformToWeb([ + { + data: { + width: 300, + height: 600, + }, + timestamp: 1, + type: 4, + }, + { + type: 2, + data: { + wireframes: [ + { + id: 12345, + type: 'text', + x: 11, + y: 12, + width: 100, + height: 30, + style: { + color: '#ee3ee4', + borderColor: '#ee3ee4', + borderWidth: '4', + borderRadius: '10px', + }, + // text property is missing + }, + ], + }, + timestamp: 1, + }, + ]) + expect(converted).toMatchSnapshot() + }) + test('can set background image to base64 png', () => { const converted = posthogEEModule.mobileReplay?.transformToWeb([ { diff --git a/ee/frontend/mobile-replay/transformer/transformers.ts b/ee/frontend/mobile-replay/transformer/transformers.ts index 1527a24d7dbeb..f2b7324a475fa 100644 --- a/ee/frontend/mobile-replay/transformer/transformers.ts +++ b/ee/frontend/mobile-replay/transformer/transformers.ts @@ -105,6 +105,10 @@ export function _isPositiveInteger(id: unknown): id is number { return typeof id === 'number' && id > 0 && id % 1 === 0 } +function _isNullish(x: unknown): x is null | undefined { + return x === null || x === undefined +} + function isRemovedNodeMutation(x: addedNodeMutation | removedNodeMutation): x is removedNodeMutation { return isObject(x) && 'id' in x } @@ -218,6 +222,17 @@ function makeTextElement( // because we might have to style the text, we always wrap it in a div // and apply styles to that const id = context.idSequence.next().value + + const childNodes = [...children] + if (!_isNullish(wireframe.text)) { + childNodes.unshift({ + type: NodeType.Text, + textContent: wireframe.text, + // since the text node is wrapped, we assign it a synthetic id + id, + }) + } + return { result: { type: NodeType.Element, @@ -227,15 +242,7 @@ function makeTextElement( 'data-rrweb-id': wireframe.id, }, id: wireframe.id, - childNodes: [ - { - type: NodeType.Text, - textContent: wireframe.text, - // since the text node is wrapped, we assign it a synthetic id - id: id, - }, - ...children, - ], + childNodes, }, context, } @@ -983,6 +990,7 @@ function isMobileIncrementalSnapshotEvent(x: unknown): x is MobileIncrementalSna function makeIncrementalAdd(add: MobileNodeMutation, context: ConversionContext): addedNodeMutation[] | null { const converted = convertWireframe(add.wireframe, context) + if (!converted) { return null } From 060ebc2b0b56e51fcee2e12e4433c38f99911e2e Mon Sep 17 00:00:00 2001 From: ted kaemming <65315+tkaemming@users.noreply.github.com> Date: Fri, 22 Mar 2024 10:59:12 -0700 Subject: [PATCH 14/16] feat(hogql): Add basic support for PoE v3 (distinct ID overrides) (#21059) --- ...-funnel-top-to-bottom-breakdown--light.png | Bin 105910 -> 105965 bytes frontend/src/queries/schema.json | 2 +- frontend/src/queries/schema.ts | 2 +- frontend/src/scenes/debug/HogQLDebug.tsx | 1 + mypy-baseline.txt | 2 + posthog/hogql/database/database.py | 25 ++++ .../schema/person_distinct_id_overrides.py | 92 ++++++++++++++ .../test/__snapshots__/test_database.ambr | 116 ++++++++++++++++++ posthog/hogql/test/test_modifiers.py | 7 ++ posthog/schema.py | 1 + 10 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 posthog/hogql/database/schema/person_distinct_id_overrides.py diff --git a/frontend/__snapshots__/scenes-app-insights--funnel-top-to-bottom-breakdown--light.png b/frontend/__snapshots__/scenes-app-insights--funnel-top-to-bottom-breakdown--light.png index 7067293aa1a1eec5e1360ece7c1c77d2f3e46d80..2ed59b8746a73cb5c382c733e3d4bd520133f0c0 100644 GIT binary patch literal 105965 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%0DU2eZ(@}n2kW`8;s-25h2fFf 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

_!X9%CyIOjyy`~GTL`RKF{6$ z;Tl!L_v~5PlPVK^O+~>q_6My-f~9&9_2~Wafure&Mu54(=}+t%He~+IszvvW!{DRhH;`zDIXB=xJHEq+E z&JqUsRJ~(>a0NF#>K3}$@;BHF%|UvBsCtKg4y)rIwhJ$`rcC1#Nn)Mg77zL|F_@(} z;2%T%1oY6ZAdDhlhE$v_peR2 zI+LnyHJCL>jqtV4VXnfcCT>JJFQNi3u2wbPKbpGl-TUgci#a5h3xAT{&6Nt?wT!w( z2@tfd`fy;s-gXK!pmVdS7f@|xCffQ<%q5IvSWze(a*?}7{KDSK#0qB1jQ3oDd8&7i zUU+2Pq}%p$XqDFNI84bd|4fbh9U!K&TJNL zpMPGNtj!<|*`djj>VrEBW0JjCw!HZ$zs{8o5nQiK+AgySPH-D-|4I*Y3gYyNY`9#| z09R?Mx^t{wdgc#nK44_C-nAVRuwPZ0nBzo6(&dIqt9?_H4f?L9^|-sbYEQ@Opv1C- zu-w^QGFIZEHdo$*g~APrr$6RC`1<8l6#_^>g5fECZgI@rFdP4c*QjA08979_c(eCz z{qXQ`=X0OxuZg|pXV0$A*zIh7>EV*Zsy!&QFs%d0Tc&e0CKQB+7$_Sh?dg>eljKM& z9_irtS#3!H=`Tb`fABHl)(g#>T~ZIkDHJ|;x%HXfuds?Ui&x!mYUs>?g}#lucRQ}z z@cm&$#bJy7hLQ&Urq_~#cF>Z#U3Bg?)jR!rLj2-k8M`jKADiKXrSwG!!JMbmtOX_J?D?v%`FEx z8fIarinMS|`_xI*KzVTdu+y;~h+K&!=$Nca6Q1!$3y{nY^fFRqoCc%%7!eMhzPR9| zWN#}6@ClZ_wiw~X_eRE;ZpnR^UCqji<=3(rbMVIxs*?=`N3pZE zVJxIOh44_`E>JfH>@|apr*@D7$pNwIDC$Cs!f}u4VAPHKYh^a zh);1b9W-og)#lw_hSCOp0MtgAyHTEpp6ae|7#n5Rt6h|U6WjA3RIEw8v2}4KD-Y`W zc!6jS75Df*+r>MNIP2W5bSH65D&4vp5o7exdeIi-)jPV!--x(t%uP8>>CLb3H)P;n%W~w%W302U;bv^`pXhDW z)-A%)yjXZ_W-=|Y#;pHy+AXcgXu;f`%!<^stA6o0yw(%?#n!!sy~iJXRO_!Agdcn4 z=RWc%frjo04B~4HWwN)o$7;Z+BbpYC24>&KgHkb08B0Q;hZj1+;}1>(@Cz}!&4yN? zbgRB>-QEcbWIZ-x!?Wo}+h`!=bpm1o9Q&UmYi_iD-Y7qxdr@DVp2vD3V)c$&0-2dY z#3fJ-$qDjpPzLUPs~pCM46xTgS!|}h&0_wJx4=Yvj%=8Op=_j5A#i$^m>7EVxgH*! zul)yXEKgyzHOXVZpGjxdJgagvU0!oD^Z!BIo5y3lzU{(ysWeF{5`~J&SY%3~Qe>VL zLZ!((CuAsvN}3D_NixqOL&k(6WG-`r%$X^}KCW8p`K|p7@7|wx@8^Ae)*lw)zOV0f zo!5CD=W!e-W}Y#D&z}5d_*;2;T!QQ*`1hpqfN|&m{zLd0Z;gNHz58Qyl9S`cT%mt!1&_u06I;pOAODW=_~(oNpGpG%+ck*?PF}na7`O$^ zkw-y6cR%eArjZJf;f!%ITS@a&E$*n9b=|3i8+zX$tTe8FT zlIQ)wC=jsgw|Shn7cq^0`d;$x7t_}Zx)Y`61+-m}7_af~#;mJbf!A_!ow+$Y^p=DW^DSB?03$YVUeH;;r7K_@XE92uNI-I z1k1Qat?KKL`kS|-8Z!(|SG0Dq4C~7c{voS=V+|MJ`_|j5r!e*^HI?i1$y<+qd4F7c z?OMNv=wEbLIvF+5!o5!ibzS!6%7i}r_;F%&soK|X5+Wj-cSp&E1pHy}9s9-#J4d`? z^{Iiw%?eGiqC^`9tpGBV^NZt^p%ajTeRU*8lKDuJ9l$yEntt11kg|+BW<)FJP++6X5p9*>( zgqO1kyT!#@hO;5Dybm=SIvyGRBN$DGADshFT?0RXqqr%|hX#aaJ#ZdPMqe$du& zGUry1BTYw^YyJtjvMjl{{IuznSMrnx9qw;xHK@+N;MBg;_lE@M(EQ1UY2XSc6kqnX z+&yv6uFC5dmyjywZHTxC*oQld_+^+i34*||1!F=Dv9(v4e@Iz1BqgTmi8Slw238C|IZEPbF zyWhi0U@(T)B@OWoU}xg!*nocaUML;1PgyVG0a=5y1-FqyprNfU0AN@_oa@2EF@2o5 zsqLgH=!20c<;jFnNKQ9k1R46UGay#LT99;xuCU6S1$wgd4Cre=76)6MPH*a7p#DKy zZkH9gWA)dFV~Q#~ildMG18T$`*=tmC-rudLc#uV2y)1{__-Wv?P2-PPYNc*QKDm>h zv)ss-^UjN_BFm&InYQqN@&77c(t0<;=T_}g{(3Vx21(9K_QN?%e1FyS*=He_E>eIU zGF`ZEf#L=qpALZiQJIOZiwhS`52P-~NLW}HSc0>ma5-IPt>f7}YL(9dekk>M7q6r| zwmPTetudD~X3Q;JAi90W3&$JoPCHVynT4;drlzKjbJhoPMxorgb!!hNXCYAWufxMW z04Yh0C5mSGox6A8FS0AI7fRb76BC=Nm@ZzrR0MrBK)D28S0f`%^Y%R6g;tQna`$(m z4_k~U@SB$RWZ&7Pm_D&&)g|_O-9x>-o=9doVY>?Oz7){^*NzT1ut&OZukGRH?s{JA zGcR%_ZpO)c*kTV4&#{39UX!8mveK0lS@I4Fjs@3AdsEH?ucuSZEif6r{r;l1;h9Ak zpLGBa#k5K?NtQyyy##+naOTH8CB_F=VI`odqT+^E)|V@ZhzN$HrLFBU7X3HBaP00T zjX`f1o?#9b0mlJ5Dqm2+m%52sZjrc_`N5H~+zCkEC*yQco1V2ktdc$uD4qjGj2HM0 z%ttacuMj4YY7QSAup1{kTL7zIT`f|tj?_R*O=HUBq z6--yQ$9=A@O&IS8F_OaE8yL8DLJ6=+y@)nvaW z{}B2un9xRn)~MradN$Y(9O&n`gTfbvx1M=zRzQP`9-w-{^Z|?#VidEDu1*C|xd}|Y zVgx3$6y0%F;_44FQLsT*YjlMH_79ma zUu;yNM$K0;cE!r-2;w0bwnN5{>t)+6VNsIGv;2Bv=HQo5ZHxT7p)O)~{duX#F)(Xh zSOe#?g(QYw-mw@8{Oc=RzeX>7Ie;fc?tU+?!L8KOe{Sz%S9}n> zVmE3YYHwm0+m*^tvJ!Vfp!;I$?Pw*KLVUTjQ~piV4C zbovpHKX-iZ{X1r-<@6#N0=)WJr-BAWBGQ(~n{ABw#VYNyXxrRSw?KU+m4;DFI8DPT zW0Rg9D1~?6XZ$?@IoTE%TTJwyHJ`(#BWMg>0vX>qS)-Be{Bo-eT!S?%nm;}}#0*&& zn%qt_86FN-d!9vmfStyjM=2;Tmmjgf$gQpD7_!2n=q-pg?(l5t03V*rd)c)5)|Xk# zh7WuGoI*i(b^~WmC+zik?oF$gBd>FVcQ0miZN#-w46j$ZZQJglO{}f3JH54UtR>ee zqp)i2nl)4ucm{pvZNzY{`>Tgu$4===05g^P3L`y08-p!b8!5>kj3SA8fy9|Of zeG$|8Kz#Hn91B!G$vMgK;^(dTix+4T+I?$Q@MI}|{IdAq(+ck)*Hd9Mr<@jD!CypT zuyGMxG$N7pGpe|acIwX#0AnpVM&LG{!r zFSO!_r5?o%oE}5iB%M%Dc!%ENJ6pA;kV??9KfzBl4g95=OGt4Ua9?NI4KT2XUv-0# z(vdI~HVjI~wsjoguQM;_4!sC5E}1C^yNqSN2Y&>D;{{fp2NJF>nBfcH?Z?E${M?{A z|JLPIzgf+LpNgDj1&^BF1<%v2GAsDJ;OW=oCN%8|aTdAVL33F_@ph5LJ^}Tf9=zv5 zbXMPe7CF|>pJCn%M-?@-d1ET9i}nXJ{@4P_t6_g&rHu`N&nqMb^mTOZfDj9j^0~R0 zQMAN~;eVa69j|Y&sVXST->fmus&^;HuhmRR`M9S ztHiq-oySid!u%p7FY9nvXs3ewgwkBp<(QKvgdb)vZV#hjY+g)0%ADM@U{M!M2STnT zEP^|}a!?Zz0WnkOs+GSTItFDtgv!^E>@zFwo_x}*bxv*}uOraB&ID9KYo|6Z5{dRz29q}0W69H zfu#O-PkwLnLYG&m9t{?9MpXW7yVRy7*A?yhvm>6=-P2E4Oug z&A7|u7t0{0{Cbz5;3oVSjE(35^s=m%6GA$?DtGej&uBe>JP?d?mALv9mwcgb3X6}& z*c~%>ww0PnyuRh#E7z>qXwXe7VG9-p$P*q|4XIs^zhXa}`xSyn3@72Q7(x#X+*eQq zm$59^2)z{J-xZN}OhYocJw85cGDxlIu$k#b&R?t>n%q+6X}Qyvm<%r>e|v%O3`F+m z#f!TLy%Vfbu39-90}R#je*5<5&6_tF6%2>@GkD*5D7v(2T{*v|E>y{P!Q-v?%9Bbj z*neKglpgXhynl8>+p+U{JEgr3YG@?!4vx(^L-+Gacnmy5~z`*&JxqOpA_Q369RWr+|ZOEDe-_ z6x|-`1KZs#JbWk7V?YI@GZL6kZ)Q(c2`m~fkftFbKEUX?J?tiErT7gte-8k z8a|PmkNaRd z81C@Y=A)jzUWtc$YRC20ySB8v3Apw8NC?l#9hBoq!qj72k}_%=>@6}~XWx7{53)$- z2(a?2gDIsyprq{6TU3*{H++$q_zXg&1S9PDjJzB$-E;GWm}o%#xPw7UAUf^XwM%-0 z$q!TtOV3_@GX^qvPW^6Dhn0W2UOaiXFCpb}WUdi4+RozLRVCq`7jAHV}x zO?iSjk;ovp>jV2Um_=%NHcUsJ+arLj9kkz9xj4r=A?ZnEHve8Br5Kl28r~gWZJhJL zb|V|Ruy6?mioq5y1C-?2_i{u+>2w{L4?ez!RD+KwgOTL$#U(T8bnbB)&T9CT zJhj^0{Ys%;SEgTrJ2W6EX)ob!k1B-t3Z{Rt57edR47J!pL-#PD#yH(EKfra>4Yq~4 z%YvO%cak>P!3jQYp;Lw{NZiJvvY@T7mAdJLwY?ipS-_k=V*gzCUe_a_JmBP#;|E|M zzDy8$Qv!>eJGbM!K;Vq>iHx=CMcd>?P72~A~O!wFFRskTmhL(3QVy_nKNM9J}AqumX5}<5n6Sd{yn^!CG5=t_I)GA=LCDG7Y3tCp z_v{_Jw9lAHUCr=h*(L4$!!NJ-$K<^Wc8)BMOHN*o9=tS=M*s+^o`6f zf@-SY*jteM7_4|(KX)fTxm%EKEW;f^d}I6;70O-pfew;I0){~iZ!IdyU|TLTegMs_ zV;SbHZk~-_;Gw)4DwIMj;B`-tO-tDHi>!y5gf0s*b$q>d9C6ZW{-+(>pFmL{H{T~H zq{1h6Jvu74Hqh9nyFH1SO~WtBw<`76$DljvJ7UP{BJAgCYY|)ove^euo?O1to@B@q z3A^PrfN{yQp=A*#V_2T6?0Mklw;Y|Z-03>O$d@IF_(d06WM_HQoo^rb6@N`1oWByp zeT*y`m2-D8{Jm!8f7UFp%A9(-a<9^@abLSn3$QRtKbk&Ppk zgv=E}4$aY*{T(bd)Il9MwVkN|9FOn?4CLnHlLzJ9WDjRTsYne9Ik^b$+`03v?-?%i zOvgzsL8g16KSt{Ms$wGWJn;gH5YI7RcE>8+!1to+{O3OiU+RB#=K7PQ=vYyXN6;YA zSZAFc>5)e*7;ozkP?yKL!H|oGXDyxp@rK)n%Ov=alh$edXB_9`xNOc@9mlyj z*jY;-tLo-yZza52(QHDmr|w8uZ;-C^jvY0ZHoH5OM(Mlt%xxdF=*?H~93NQpn94Bq zJ$7h~S>=#%cbv+e9}T(|w_OSQ7IDqe(sF%(pPye}1WraFg6P^FewgM$S}Hep5TkRB zA3qLfw%riok#rtDKUxDb6+n5oiQzif|RnOwUI@t6aL6A`u8c*!99-&_D>s@_PH!hz#b+*n=b z=unm8m%eF}G!wtJwixY$^{lK(_B~$FVhY9Uc|P~NyvAV6IIbDP7oQ35x;2ROgEL6vWh@^koQrCh4W+&`gR(r;EN zp&nQ7=-!3|>?}Bx7b9Zs<&_7EotT~L_kHN)wQzoX=YGZhv%bT+RJ}j8Sn39>)9%=~ z-r79uTdT{bp0)(lHthJ|bBs((cgXM$9C%0fU-(lblLbAAT#x|lJ z)WILnZE@=xSAP*~M=n3Pk5Q-xo=7;0!4u035`oo#FbbjPHA|ZVoGlGd_?crrrGsRjz@L$&0hQhP`VB^GoB>gs_%@Rna!W5x z%|BpN&+Zj~F(l0mHjOXCymabnfg7C~ybnr+UWje$8GZ%9-{D=4!;oyQ7&&9X^Y72` zIQGh(R`HFNmTuz@T#vrbTPQ79I8qVHjF&Wu}=xfL{>7f9Fq3-eNm&U<*28ov-M+tq;H(7F4hGq|1Y^VS>iX zt5gwpE}-5f=_hEtlfxIq5ek62u#xn(^^t?Y+Mxtd3erptiG@ULMlzdj z2^C&7YHl+32bB%Gx!H@@EqBAlc&d9|x-i6U8K;*lRSDi8D+Db9gykzRJ4FVD(fC_% zh+T^wdG3`&mUDnc z{Kh_2&%dfu{E#$L^%^S&@=XZTO50lxu^ z^KR3d!~{1VNUSi6ZXI$4iW?La-pnFOBM$||Ag6na#rcHd&q_`YOdk{>6kLCZk4!Br zeBy%b=OqOVV@z?+Mf{&;e3s}xB}kn(?yBJL7s8@+>zoew+_20{XbGDaHt z8Pt&rUI(g(90z3{B&FS#Mj8YoKW2R_sUz9Q$NBi!e!W&_ty+PAleKx}O?F_Lb#3)s zPMaq5p`$IACyl0`eS3s0@@tU+?P@GKrQy@o=&Gi0tg&Bz_6VaJ|5 zCltm3bFtxF0-3s{6?YuaAw0)dk=s0nWW;E*q0S`L7X@5B9x!A{=?yi|VI+e1n5a~P zr~ghkC!%2in&r(WCp96w;7(|4or(Pywt3w%z!VXk~xtCFzR4zg9PYU|1?12{AO-e5vmQXIzR{kdwDgN_>y0 z=be#+t8;tOotrjDH8arrv~oAJwp`)IV1ishfZtMsxC8)xp!vD-2IZd}g|W?jJ;@*T zPx}lx9UiY0*`TJiYt10rcKR=30H>hMLg?*6ac~Q=RuIDo*oiN8Ao!4c1{wg`BkLz3 zsc=KE0%41>Z8#jJLM%A_Za}bb66hupnd3=ab*4WfP=PZ$XwPrk)c6jkGY2EdYvOK#(^KFVyTYQgXgm@AqEkWg4bzXNntIJ;Cff zR7xFR6$|N#Vtyur1#jtM7xJD~hEu^b4TlmW0snKcJ#mJh)iQ6>Y;7H`4ecRk#W)>^+ml; zCPfq!^^PU}E2ZV`cIqftGSOeZ2B}$%Zrf`!UGiW7qhTz;64+!c!|KP!^MLJeQf{QX z`+{x1(d;AwL5VM?x+Ui5TID86J^N1p(xkBL4cd2oujq$}Ht;ieW|zM}`|ut_K1-11 z3txR;%%gSNEB^L;WS_Mhr;OceRTr1MHjY=>LGnSmZO|keqSY(vGKbO1ZFR!?H7?oQ zS1pf|)s2y}^D!9EnKg@LZV58h?GCKvvvn9)F>S~HK0x+_q20O!vA1?@A`k4oFTXnT z#Kql{_WU--LVU$?urNrgo*Ftc>y;str=4}8h2=ahTaLIjP#0KRV`F* zh8f!}2QRjT*v2fNrSF-Pl+X01XtM^bk{pG9&5I4*9lYken|N$5*Z?AnXw0tzs-@{K?8PVm?}iEBqJhNDk-(m z75dGAXrtML1T-(QU+z4OS`(ahPCpA1RrrJNf}+0aFMJo28yRC`t7~lM2M9pO?_;+qUyqm@&#^ITY;w~8wZ+Qu~eoB0(lUrGEzx>&zHZk zR@e$GgGslX(Xu0MYB4th0#5qPB6V61oCkJr*CK-6!Hk{cAv7;ewMk8b#OHn!(w zr8|X<>rRY(SPf^=%MpSYd~+DnBjx1f$uxw~W+m~QB1=#p;4NV}J9YsE4{MR(!x*&Q z$@H8$DHPG^&~6-f+m`>g-tegAeCLuM9G3aQS7DxhB92 zJh1cxn1BRx#gCb5af(iQ)#fd;)N0Frb1NM~WIyA*+eih|_6{;t#sufMiP zW-$F0ZW2Y%UnkfjI|s*htQMwgT!&fqH-RcpyHL}=!@eZbT~Mc<;EJmglRqTQTNOM6 z!yc+zN4K-=hx?&an2J}xmgi5gQ!0b6Y>#Md5PnvG|B;_6T9xhpduLqJ^b5~! zzKml_fS(_hD_&}37dqLM#Txd1R_jNoz-0|mk0B-)5EPE&{v_qU!A4H{xu^YG^Bbtu zns1r2`sY7L;5NgqSerQ= z))Qu%yQk0U(F|`xCTMKyx`6inC*kPF-Ezl{36Fp=QF7=Z9pNFo@CcuqU(F@4S{Wrq zlyo?qtJXEY=<$vbi=Xn$hF2^8yXgo2d4vBS`D?i!0XgyU-Us=)~s4{<2ikhS4qLbla@8Z&n>*%PvL`~ISb z7`i(hSzksoEc6Hb)W26=Xf*qqPjT!I0p$M{4DWi-FAsV5+;-XW*6(p7^%OI#%Yb*Me znQTJQ{d*lQe*V^>Z?hw>X@qy)G3$8w(Z7DffT@k8>%sJ<5&B{Ml*`(Ge%i}4L~-5l z!>9+rb%m`mu18e!v|0U-0K%w;8u>QVul2f7^~Ndi>L4SE-hy{Z{On->T{bAFv3TM9 z`7?z#mV;_{qfqb$TgN?-w!@eR@?j1I-@XfFn@G=qX!8-Ubwi&#@xsM&78WxzIBAnj z<_LUkSG#CnTtkHfib3+tx$K|cF=X{BY=hP_GDc^d4pZqMSPK+NBmo3tqU5p!*a&EY zur8&dDsDvbK2Z~|pUZ>{Tn0b&Bgu7s4FYRtHmSm4ibyn~#0(K4^ewne<8GOl=z15s zp-8~t=EqE2;wJ#c)pP9u-Vg&RA3Bpba~|LTxZ$4zF!pOGe)o>_UeL2ZVz6nrEjKQs z?Ud;wTaTaWQsoixBIzT(t0}zOqeV@wsvCBE0lU(OCeG1l=j*y|A9u!x-;U*ynwE zbxAp1?+v)eoEIa)e)1yu0_RH_K(2RWGv@Yz?YIJTlJGu++aKTqZU>PM)RaAZd?m0@ z+ny+iNz-|Y3r;+zk|~(+xCNn#2;?ca{oeuHNrtT*gvm?5<|-&!mxYK1f3@4k`%UkX zejF&P=uef2)CUV1Z2(9@&~*fs4)~&xUh~=>zlRU6BMI+BU$>K+i%ae_ag_&og^c(l zI4HUw?CV!q# zAK(rA^E706<}j7M1m1}m+ zcLB5!H%br!Pv<()BYmybZU4k5c5&a8wP(D1yEYjbeYR+zdA+3h{4oFB^e;mlZL`HO zmd{exeOmp=_?B@u9V4R`P^hn2z0cy(646;j;X$4VC^p!cUO=U`RncOG%MmrTN8cv>KPGK2^-9+iVIW;z^1eV1O-kd# z;Q(|CzHGwwfO5JmTW$j$zddlTc$e&@Xi1^8(`An8zsLfT`Od_Q9Vl9#Srd1EC+XE4*2#+Vp~sMIEAoo2~iQy zH^t4DXAcNElRj8tlX-;m|vf-@mKfo@fdh_-&ihNYCtmhtj_lOhA<&!Eif-F-tY>EUj5S154~Tre=I(qHDZH29sn zcb8snf|DykGJ&_@gXqb&at7al!_ocx`5_BOqsAnI`_ORi#5Tts%gelmj(X>k8axid zCm^*NvRe%6+Htx7j#)6?mjkh69s8}!urp2{~bp9$vM_A#x zpeF`13tIGHaA}aq6%2dzyTXf~UK$Ysm?tC}Y?2(@t3ZQ{FnGlDGb1sqR9-B&O{z`m- z0C^T#OEenO9B2EV))}slDy5{~nva}J{__w70@va{%sai@nk@t;8urR7$qYe~Hc7IF zylb3IIzAuTYCcf&ReV-`<$(+p@eJhzn!(W@%v_W`d-iK#LRcU;C%J9mHY@a#)(Cg-cUZ9@_z}N5NVS(jpRtUk?bt>NWOmn)Q4?*;6A=p* zkh6E@EkdeM)V?q!GB-C~MQ#unINU-(p&b_aT81wm9DxMKyHg-SZ57m%vI8djB}-1g zgO9=GXWwpu7y_6|{BVuz2_PI~6^UUf8^3VOux9#58N2{X5jRuNrG~{;o>JMVlOGRU z+-J8|MHlx0AMS%)-HgN@nT%)L2eAq|rLi^lq)dV;Xor_Pw;fmT9bObUe_i?T`#hgV zSm9r*p2VS~x&{OM3q@GBRXg<>lmV;G)HSc^kc$&V-D%qq4HA$iYGJ zswoGNG8G;{uEk86PC}dS7$OCmDJub?(PbrX5?gcz z-hU?Pd9P2z)dP2>g56&!a-dO6966ex#heqPfbasL?c_5Rl>F@a7i;6S_oK5hFtiid zf)(rhi0fhzIIB<+n&QhCkVQL^Gro=(G7Z?JA4k)Y5DF(5Y9# zF=x}>oF6x?2lwygEM2SSv&4AKuZkw*M$Ip`8sZ4;gf9v57t)o%JSmfUfu;)AoEpW& zqkTROdmN?@TxP9XxVH-JiXX6MK8G_a3L`UE&L?BuGU+0KvxO^}={4q&Y{P3WCVf{7 zawHw^Kg7XTSEY}NB&?>58VBc++Thyga#*us$e1U1Y6!yWAIG6nn8EG?2XiGbM(pD- z6tIq=Z@?&pAtqzRQz3Wh@atM}w_uRmpT?$3DD(jM&*2-NE(;QggT(xVI#OR%h5hIV zTFC`rWIV|duT50TfXzgxUU*r%UGDNd{s5EOQ?POj1BGXLq+JFO3T#o9h>Kq~Ylz>n zFdn-2JTsFKtiaD{Mvt#17)ebarfrvyU_l5a$Sa1Aw<+#WOxVl1)BioKH(lI=4Qsj$ zN011jOJchU=6zYOrLyoF-}xT#!;jbPl=#cYHVAx~nX^FZ9e0mAepqpXk$mmr;u zKYg(I2VBPP)P_S{MuJiA0$mU1)&I8*dcA((fp9Sl~QT^6t@Qm@mNDMxPL;&U7 zyGgu0a^tr-PwSCA>f_^s!Jm?FDzoU;Y4#!co}?rz;Fgg=6xno{G8e)05wOUtFbf0EyYEom4?F_L(e_V) zVk@FQ8|bY5rPy33tdg;In;|Zfw9C~?2?rXE+n~eVK@+*I|NhY{Amc|@H?EoSfxtO57=hc_FazV%cF>P^n!bTzGgV8LXYutjKS%^#} zsTiYOxcBVA7%0`Fw!wq4ZJ5(oazE57AA)lY_ zb*3t1p}C~9lCC~DDrz?xr0R{uY{r(1PLovAJLw({C1bNJ5xv5^wA5UxKb!GSsd`Mf z3JC9CYK4ck|L=qg{~gEy?Jt9xU%$pbTKT{C_cE=!7i0vnNlfD1Bj;Z+?!;@S@k}Yq zWn0<3Vw!36Qt`>#Vo4?49ckD8;06D8)fz;&aKKYaGt z=sOmP2kC3CkH62d929=1a~zUL@{zhq*r6wH@I3>84S*ihQlYc_(cQ9}UG9Z}N003d zp?^ah_M2K;CLN$N7@GEX$!&Q-4%6@7VE6h!W`2my(DZ8iq*G};e?79-mBL9`Rq7{{ z`a6cH%v7^tejT5E)D{5wGr`V5paBuO1aq z+MG-Zks>&X5FRuiQW7R8NGX)nx0XU?2$L%T7Kd+ib6u>91#t7GP!L$ryKX24y0vNZ z<}Tv7XRR0yNe30~j^m(ez-lTsBQeq}dq>I2KPWO~Xv{0e zNn=<@u>f~KM_iN`>mt@@=kmR-Y>`keRgu*D!{#4|s5eeW{73z|{If;V*4Njw)mzOh zc(I-V?@9T|l(C+}#!)KMUVZErYCw`#QVQU@MvZF-Wx`Qh_2S}Ne@h!6h1g7@(c{M( z!T$FEV#$cQDR% za__s!yB+Txzjza^0yk_lHV};fOz=RPA+hr+E--$$Ga_R+$)rN=R6L(FwY~&yz!GQ$ zzeWE0FfdTt$XT(;R+Dk(c?I+c(8};~#gd;;R!$n|6l4_Y+rQ)tk_e#41xPrFra1?; z<6anQ4ioTm-A_MD*!)s>@;&O1xHy+HXV8NOZV2;BX_c?0w5Rc!QrVS$dOZTrTW>Q> za=p>4nrOZ#eWiNC5}hSF31=Fd_6rC+K&}A`H+sKa#$PiM@Wg zAwICp$x8uwD9X^|Dk={${4Hwez}1nqV62;Korss z@MgEOvoC|s8^PJpGMcRU&eyes0{JiQ{P40InEturf+F{E{G@dw884X|li6LLrl>21 z^nSh(+VF*>L@MkYFnI|j35|zvum#BU2h@2U_y=)~MGb+?m--n8qPSt3!HP02%aL=IW{bcval>>RIq~Th8;Bc>66%s9;BB*xNyOY6$FB>0 zc~&IzkVO0dxt)YUBEleoaSU1AfEY%OxGmdV&&EKE`RYaE)H0+lJW>0_?{!-F5Dmeq z9H2XbOf=}Tc%nu-99~W2YtUFp+uGXdovet&)_FRBR%360$a`t zY=OZ*HIn(YOoAtZhtBW{yY}cmc4UnB)liV)B-+vtQRFZdMR;6S%|nf8;AD+Va8agH><1ignDd0q^5UoJ0V-=_tBY4%F zO}($;!(I@&z+NNG&#B?oyWmncG@Im^6oKeW%$uREd=7%mDR?Pf8E)ZBY)>=VNW@Oy zh@Ats8sn=>{T9EWvL}jS9Pi39p=26=(^~(^`}{}GAHdeJ+pYB7b!zuny2xEf!z$2%d=AnARNcg9= zBfp;ai0mSuObU=CbWlkY#M><*ZLLH}wD&O`#T$jhS5R}^j)vjCkPv8=>G96eyd z^1zcPoa%g+`F9wRn?wZq98n_aEVNY*{(a4L_LtxLFJHC*4&o;Z4eBnr46(PaI;B6{B?l**hN1uGv*v%M8{b&+|9jFlh;G9ZQpgc|fGy2N?E+eS@Msbt7s{EWq7zLxAm2cb-UE zBXpGzqad@pSQ)$uC<2D03>=DO2jl`V-=o?folsxjWvJRV>(6va`(kDQk;t8<(Lk(p?7SI*8@()Rhl$Bx0$>rbgQDqYc@hN@FUc z*eqyx^ZitPTGi>~GfR3ZL+;`>-hd(sm*OWU$@ve+W$r-K*ohN?lc4E0@WrBu0XdA} zcuFLJfS45{Si`E|f ztNnH6RbvYkGUR1GtsZsISpWGjeWnPbgg^Q2j=uk64fQ`tk$>pa{ki`P0;YSot(s^q zPEG=ZX1Yg7n7SW&J1@=?{&w<*o*P3ZsbNbdUlE$~7F|rz%zRqAs$tKL-w%%NVMX$X!rY!?*V5Z{e@K}`S>E%oYNzry!}9o`y1M{6qGM2BT6zWfmuSThs*ptp zA_$sj*D!d)#`M3C$R#Uhn-P6C z5*w1Q0E)HK<0-gEJ-y)ovR$Pvh8O3RELKjN%ejPV#T5e`SVp-DWE;6`@|7VS;0FjB zQn*U`Y9c^bErcwB7VKYAP{Dqa%t1MIS7?W>FFLYFjL(7x`2OR^_%uvn%tcmL0CPX` zn~)tq9ToOAd}63LTkt>bFroeapk+qU~j)8}qwPQ3uzeK!TlwFlKP8Kt^4QD^UoI-^rn7 zk#MQU0t05VuYX)_QDo68Js};xcBk<1@n@n|WNfz@?l8@lC+Pe*)upQrO$P&yG4KMSqD-fJ>Th59CE%YxW}QjED}Z?xG>rQWAF%$Wg3fzAok+NQurKW_icast2N<_BR`ylC z*)G607xID_)9jQ*zes>)d~B=+P&7R~eZ^>jdS0D6Qx1nz$xX9U)jM@40yY(1tjGCRu9Q6U*Hy2NC4Rz?*G6Y0Us!LA(&l`pGJ>m{M_tS;8 z42#g!3_N>evmM4G$=CMP{^g^Lyq`T%I^B4K57 z;*s^Y_hImY5zTS2G)LNCZEt@PRg7X0rkvUV;R`B>I_`jn9m%bQ_11*f39xoP&j#jX z`sS5x-+-Cy0i$9`oy5nZC0{E*s;iD!(GE=ww+(aLU-)+4*6Yz=|Sv z_p_@^8 zLDnJ1uZxi1?2HtF>tteZPEO7@4132VZj8c?(z^@h8!eV1hkH-fRyu7D5j3RQ>wW zN&RL&X9v5Wdd}UKc`KPx2VM5iTESQ8Zz~0{R9CE$7bF zOulAgTSs;sNGeCr@3;lxL>SUSBk*qevDc(M{m%Y=PBz&t^Vy&+#DmVj$ydCWzngF8YVmdRhpK^)Io{LSspm0f!}%o+dOy12 zD(ImRulzuLA5w-7V6advvfxR~FDh?s)gxgOFjO~s@dhD3J{ecP`2DI-1eaG-D8hIw z{!7Ny5BDVPhl7_=QEk&|L%)O`F~x&sB;O0hn}fKb{Gr5(fKK$K)Llvsd0tWI=w)A< zO?`$LsTV#xI*t>d0RiNGvG}#WPgWp#1$I!IAz;=HZYC~lvG__H=EO0HT0Tc%9|fNl z_^k2jb=lnZTB}^&xT?1*RIAb9?ne(Z#vih=H?qea))WuURVO;=-PQE(P2LuxBS9JP zVQG$falGujE#u+HV&SEfg7BRS^o~XQK1zTZ5b4@AY>S~HvJ+W0)7eX@#-q4=6dZJ2 z{MUtkIg}(5XTObU4TXFJ>P0FH>#g?JYFLmgOFt&`VYk!R{+aUuCbx~tnigfUG#zZs z*DN7Fc{p$?&`H*uzUZ44KTmiO`4WY#w%qsR@b7QC4W0P&iKR9B^zUzqW@+r6PE0f( z8y~e&5d8fmakaHs+1U}m`nG?I2Gd7)?wy!PsjkW!><*{mtK-jlD z=VdH*raLJVah(nN5z77I1^d<(mz3<;)${B{xJ7yG{=3(lUmav$5#aUS(lf*vWv{%d zYKHCfupWL&H1^c**T{lqpLy9Mj=KnX-FCK@QB5o- zFKKu82D&ZgqNxQa>5PA-1vaH#h=W9NCur8YtlxWvH07vK?Y zkue~z)KYq#{BUDZd$h=#{0OwJ<78_~bl#Xp_-s8CT_m&aa?`{IF10i-3_^asZts;k zB#ztCKYPB-8R_|6dO>oJLEdxkb=?pD?RUuzV=VQ=f)lIUqbA9AB_vX+mX^s#uDC_=}%@BuR^%OQF4YZT1FMBJdxJ_u!jLeXLM6WW6xo6gpEt%@FnB z;eJp3k%_15MzdpnK!=`vnc3-i|NBthNVKuvdV0>S@v)jm>!PNc#W3CZMQW$H#o}!5 zHl~ADa$>bssa~JEm3FCWMED-5u}2`gyZemOK>PS=>bSG+B~L}IQqc}Hi=DpRl1D|aRcnNQ475qBEbMN-Ny1KC~(Lymzc_Z;dqkBUl|kf7*`Zf`Rq^>fH@Pa5Yr*Ymq(dJ^Gm;-t|*t&Y*Vg{;xxP(0H+zXJja9C7e#^ ztG!f)zh*z&QjJ?k=ttL)>}~WB!xmTMtsSQ7%Aa*N>AD0XW5oVp3prq;6?Za0Nh3;= z`=tD%XAY4$NFmu|0rS1mcTITJC(jJ=2KlM+eBI}~K^ev$YL1r$i6j+wM_kk=Yjk4o zx-4tgxtaDF_nT!*5MM2)rsftEJ%wOen+vW|E z$f|nqG;pg*h8zl-;p*#A)D^U@v)p#TQANgwMI*~vxmj@G+Xr>W>5yrxRXCDmlf~3rm+nKiqpA@`V={QgkPad7W83G2h42|i$VKGe^Q1Vi=_ zwrwo7*qq47jjX0O_V@As#wmk!X&-JZzbkm5pPl^WgZA^L{f|exb~o9|9F^<8P-Q*D zE9nE3!PAV(yJU589TUEY7VS&BGUO<$hW3U+QU2UHFYI1Tw2_9Ia;5Of>q_pKXkyfm zUZ&*{!%}Z$YloP?&19Ww?n*uS1>jm9Ir9(Y(VYE}Rcg@v-Py$ZBE>MDUvD|h+O>60 z_`@|{UZy)PEp1%l{pEJgP*cJyG*yhU-wyZp8`sWkslC*X1kd<$^mU1uABSqI#&6x! zXx!~C@rb?RY2a0d(OZX@Be(32GJg9m#rR8V7O;0e4ta)2=QsD+`;a>@STHLO2=`5t zm>7S0{*0XyrsO}rcP%`6>AIMkn9q7`)nkT9c**))&hY1bD*p)9=E|T^RtjFLde%-d z25e;R!7q`KU#&8F?XS&pEMK|6Z}K!W-4@F%RSN&wD7-t8e{=> zS#&jCUA-W#g#1YZrroHz8U+U-d2GtIi|ZTlVy4sTl9w}XdWpK^qHDk&I@6zv`HT9> zSH4U&ls9yXy=c8dzxN`SYsFK$$gd_Wr#~d=y@^CTQz()T;N+0~=~#DpXwEJGMIwi+ zvbd@W4YN?Pqpq`Y54l0yCORKn8b*>If&8<-zutuNnaFUN32bP1eC{)|EUq>S&eVlN zaNW#!@9^R#gX!Tz^|?+}?7jKdW?`=KXhAj&;StQmSrU36J-Fy7A>p%q=Ld%bS;e5M z95c>SGgXtN?@B(WU32R9dqiHYPMT?A{({&`q_cgXdi%3Ov)3fZmscgh{PLu}iyj(< zCkGmaz6}h-S$99vnqM(l7mtF_U>UpbQwMT4vE_<>D|7z(cDjApVzY%)yplaqfe;C2 zX;8}fbKmnRS)ZKWn8&kMs54*^p+nYXLteFH9?HVFvqig}3S4+v8Jhnbt}T5Di<6(? zzi>M3&lT$XvdgL_Ti=H(-(ma`lGGP^2ki&?{o=%~{@5EL?jVO+2m2`ROB#pVGLw0a zdM2?6c_Guf!`iPd);A z_YYmP$_C4|uj{@9$T$I0tTR#&#I63w9Bn9bzwdKOSEO!d7eIhacFuhk&vzd6V_&}P zTLb2HfAV^05MwvcJIK`)cXsC{X6CrwXA?}PeE#MFn1qEDt>8w9`N;RX{2Hh8$AaF; zmOCCuoy&0;kHv`apCHSmUl|e$Iq14*?)~YL$L--A57+@xq`T&YkUP}Ta=PFb>qH}> zuh8?wQk@imzR<7o6@T6g%kMYSC0!PBFoP7Q$k%H+1sfA@nUsBtdGsvd=I4V*S7;Ih-~0^7qSE%&mDd$1vLVG~cm)zIRAhqVcWiQ(%0s+{!{>n5q3{ zGq=8io>>0&;$NxkVRavWXVrZlwtvWlG;js&?9oSp_LbsxBMs^pPvL)-G25n>SjEKS zZUvVuYI3IQOa1gvTcm@5OGG$u3R^h6O%7JeLoxe+T@U0w04OyuTj)j!?Xx%ko0kfQ zED5zJ*~qWiE5RB+&}ebu5sI<|lGh~awbudZHy6sP3K&^bS$pENaqj$FRa)H6Bg~;Gfr1yyQL==h$h@`bbIurdjQ8Wc@qXO<_|rC__TJzA!di39 zIhSxS!}XVjS7lGA0dPU^+Bl|>t&RE6ppawin~kmY@+~%PPA;frO#bE9WpOU`^SlOn z;28T5(m+OOpX8QEA1wUtjZ_cRJj5XoWrLWk@Sb!Y1BD4!4ez$hwWcMSGvnK6+WEfH z3NEbsGkoh2UJoW|`@jDVis_5wBylUn{9zX!=V7M45hnds-(_akjdpisvh&&uKOQe# zvt=NS?p|Lyt5JMUC+atz6voR0Bn$x03Y+(GtXOVo!4)K1x$WWjL-{+wvP+LiI1iwf zf-I;ILIpFTtgNgh8kGXzhVHCzE_9rW!U!0ST}#3ew~s)B1XW1%H6Vh8?6SAm%xR~5 z?nnuR+bxp8z{}t`gLg(F=5Ca@n>_+NxG#^ZK#xX(af7Nx7It7}o5jFGr5;A++qY39 zB@PP<8`(5G?Y-2Hf$mt@J+hd+6|aB(_umm*bb2l}6>rUZb@0=OhneX{dz^3VZsO1A zZ4v#-YG5XF)e-J)Mz(sT!A$#O)zsnW= zB(T9Wq;iuM6&A$iylUZ_pn~m4^ zONHboqcRtA@KGi&=#U&rw8@k@WoAJ!6x!4jh}(Pxk2^&eo%~Y?#Do-$Se*-?)He_)3k@hxU51 zKKVa6<3&ez$pC>%L;|pcWXxVzNYu!W@w^JBl1#^_3+@e`xw}1_T7tIUa?Wz-X;itE z>Rcpcn5iU=NIW}D_rBf_!3j8u9;>8gYwYpr2%pHZVZhCkr_z0cuC$-oF0s(>Dg3Lz zV9{BQ#jw^!vm+I)BWU^3!o%+rM9BZ#i}9ALTYG{#zslc~w30FygWkV=Uo8j6lq5=0YuS)%-`KzQy@C<9w%w5m z5{5-=-Eu^)RqJPgpk0dQ1`j;!r+ZkO$D^(PVTnci+0E2aYZqmb#gOwOJ2-oo<;Hs#gcJdN zyY*M6R9JU={GR0XM8TY-P?kk5xl{FXEglPcMa#>TiJ!wZ`XGJZ)spQ<@Z(Z1-(#XN z@Ra}9Io*~>QI_{T)+M9}TkEZ3|H3&x-wyqpAwk}d#Z*c1xTD2#ignC{ceLs z4Hg4+0Yw0tKL7aAhG1bJ&vMgths35g#_*JjwtH+;3K`Xr((Oa{RPHn^iTBfBZKBuy z)-DSgp=7G09G>Z&Mg1D{TiQeQ#fjGdN1|L)hoBSuUW`#9iY3U zxp0vMwt7zRwnEno)AT1=8B#ZnPjUfmK){}wEjZJiR^_qwBkkAYQ)ZS4R%R2~W)K{; z{b%95ti4YDTsnyNdH-fHhB9c4mzY;7*T4o+gt|vpySXhIoD0-e( zQ=Y}pLj%-Pio{dWd(|>523|T7ts1IJ#%Vp(15Vgt(=4m)xLzBLeKfM5ZcZIOvuCe9 zj18?Ur6SPPyB*ns>uu@HHsn=DkTdfTu{cQ^rR*_`)dn$=fdUFyf(A9msWQE72jv)RcoRfy~LILj9yQozxoi{4#JxJ)&gUnWjj)=;j`;= z>}Zy~!*=-+C2j{S7A_JjcN5sA8&2`IG~9_@9XFd!p+ICzBGa)Tv` z<7QazcOWsVLF~$TO$-a_mg-{D_GHnLsVvOw8kXo4aEyV+l&==vZT6T#0T)PQtVu+| zrIn?wFlnBCT}jW@`e7MNeO%^~#}3}B4)~Ls zw}AiNoug%#r(dFkyj$DYTZ2Vo49Fx6Uo{W2r=PXxl%S(Cl|_!f49D-=zansPem-&7 zOUUul_2KeAl72ltnI+%b5}pct;7so-20_PhOK)oL@1#=N!U&0$6U~VmsWvy$W|Xq- z5k}BC)TU1@6d3=6a+Fb}(I0gmket{nmo$3|x>@G8_aWXS*8_VbOD21}W9vjEs)PG^{WS4!X+*v2QxdyeA zp1K_w$o&vcbk zfjB$k%KbpL0iQLP3b)Pg!NK@g4B9OUDOcH%U7>Q^8o4g7itu`;7Blj6iLn^nWYfpV zpQN(B>k8pC)|yIg0Ei^!y&25L3H2y0FwZ68D6dQSZ+<>JXF^iZ$5e_gd0qT zsxLgZ0$>^n;V06zMHeG`I*04G3!&lPWptpRG0T|()C5^~Pd@4f7k<|ZNfMEpLxokb z*HQ6{x4{anw07OA(7fYynuAFbg8V`tt+sbyQFpt$aReGyehx;$IHferc19>SSGvxv z-v`+@MxfRWtowGtq^ZMhB~cv8mo~PxW``YHO~0+gHr z=kDf+446<_K$i#w&Chv&Ksb&Kx-mV$_VVV963Qf?>LJ;momP8^8WPGP2^~-SGL6%Y zd5i}9oo?kg)sd%S81@jdB|xdtPtFQkum5}{hTpCB(JuaMT=CDG_(WbtZg#Adw;3K~ zXA7ST8tT^}x^+G&2=LAwE7^Za@OQ_r%1zNpyFVHA@Ha}229&dnE7>=7-CaZ8Qrs9zA*o8fLq=TDL?4 zEIgF~e&=LKS+hm!WDcMd11xfhwKW8vox_rp-TOfN)C9FU;8!U=TXta{wB1CoZz>Wo zq|Wq~I*eU&neNtCmekM$)U7MJU3Yxp?fOf-QcIP23jQ`|$kpBq5;U?L8}5-(HFo9# zg!5WG;Z0;e{C?4HxDo?I6?0w+m|l`5QM!UAjokBO{Oygum#wEdhQ**`0|EsXNq9~k zp!>6A6xp<=K_8{35baa&a;6s&bFPpJeDX)uSRa-x=$D$$%ab%bB_I5TUpGqP(#Xz) zo!D|MS2SC_B0QRV!vLyDCE|VnYuHSONncNueL>H&X>e7}C-3v;_|4T4<(?dxF1kY) zHY);jau;{qPR7+;%sC67TaQ&lB$yK4Bl$>rJa3U!Q&P)N?573c3$+cfy`68LkW#9n zQSl1lcV(Ekz=tyZJAip{(9;VfBP2NE!07Ngi?oj(Zl}N>@TiZ*I{&;Yq-^(gxs3M7 zX?NS|*Ta)#M)H8g_H2v>U1kKl#Jv42n46ucYx|v!&SLyUbsRD+Z>N`8Pgu{7?8F0g zEDhu}SwL;S$Z`huf@4UK{dqNADL((;)@d%b)XG}s?O2TTv)`b!`y2^`O+Ah?_{4Nw zhP*0k>Fz)I=>M3K=eIvf%vv>3I>iG2RJOm}K7HR24;E18KO0_ec2GXY9lpRfz*W)| za|UXRx3v?F$>{XfX3NlQ3yRcYCN9yIDXv zlZ<^@Nq3cJK%LWLQ{dX|chV~UTgG_{SkS85xKhqB)G5K8vUw`M&<*tdbv8$|!!J)rgY_G4s znj-U{s5Dr#gy5et7GO961q!nZeo)pDocH9{-9a_{)>PcnSX#BxVoQGP;n~wS+_UE9 zk+-1J5A;u z8|O_OYuXb!84p!~yV?D!U02w9L_>kW9lKeILmM=PeV55iAf+HMu#Ua(%y zjV(a}-4Nytg4NKn*^M4}mh&jpyO(=ytXd+i%qK4TC4qP}$2Qh68_RwVc3n(q+jFfP zn5X89^c3KeA^2z@J!ewj`Rth>UcVo}?FmO#u;kd#0hpiexUBiLbMtC)Z?xH$p~c!a68e55iJ;0CdnKtFOTqOVlAg7PRYb zv)+!*pVYNEjz-G-o2x#$NF4s^%pJk z%0=IbE%HiZ6tXnV#wCv6;v03y^m75NgG3V?vjbJX{HJFWN=*rQ;=SF2jH079QCu65 z*1fqo6d$sQT5z;+;i|}&a)-0(1o;=pll}{Ex8suLBre3Cfy!1q^4rPxktHmwAreY$fz@e}r9^q@$VYfQ)# z`&y~DHMzO(t8Iv2C~Eee>TEf|n*!xyyFl@@**9r+B7!atKEGWtu<^E5PSnW>Be)3r zu;j87CGd5S*1Z4PV2)jzJm5che(A*CXHG8WCmNQ&ccZ&aosL= zI3+k9%)B;H7%`fEZLZL^mTPg^7Z@y81rx8z(bBDbJdTeV zTU^AI+V3PRt%TY&2ApjQhO4B2=t#C+_GEA#S?HoCZO7huZausU>S*bX{->C1L3Ym+ zgx5A@-nL2PbLw-xDkAb#-Tt0wIiKsCaASnBlo7Yy`kSTxq@Bjo3bn$}>d)G1Wxk(& z)@`X<=j!$ApSA0JLae@O)%!C7v@W1)5B$jxc7;0OQ_Mp)ig6MjK11QW$fG@wjm&FQ zrIU^O2pvch!7J7Rnt1S#3e%){gg|o_41$9zUCv;EdXv#tNZ^`stR(`j!ZDA7ak&VL z*P9@!GX{ggix7!4!sX&7cRW@fKy29gIhH@;5Bk2I>!6%Yp18KXMWeXI`ZYwASW_KA zUQU7D3;aM$xE092YmaONeMd%KaR&taXH#zf^@|@o`Vv&@(e`f5b~Z=*#cjx)`NQJDU|ztO zhn2K|bo9geME|@jl!Jqb^Ml%YyHPm|igwQ1i}j5IP8@cF^xWRzLH}NU^W76C!S3#j zEYvuy?VMIKyul8dayD(8&^9b1bIF(24H?prr>RnD+NB|;hyk0CevX-?dcoKt(_s)FpNyd7*d(ELLhUz0Nbr#{A3WXl!AIk zQvFtYx~SW3JP^;+2=?MY{#XMJg zBV|B9ntNj;Q#;EzoQkLR#Y%pJd7*rxNT?-#skgtciDp$(z1(Lkqm`WVarh~jcKh@ z-MRUFea)rXtg0j-G{&TruMazvH9!w?@m%T~luJ=sh-xK9ck`>7>_;PFLd;jvTBs$5 zXGd&!kRbc)bHc7CyhLcIG;(W4zs#P66!V?<=}kAaqgyCpP)vI!J~DweSS7{YYthV7 z6`|V{E^eS}Ln-~iuaF3^$_2G_rCZ3mx+F;v0FsOMRl{1Z#$FqS5QUh|iw6!IXoLRe5ArRd1u&C2_$mKY!5*JX>N#fofXu0HrtkQsu#DIyx2x^u0Uk zTD|K_G@Pd>WVcAMo>5Td42Iup{XvNlkeki%7Qhu}>cjOc4A)KfOq0Y4_ntyW-JN$s z$07dB2hw|7yBfjzJZZ1S|XOgHLphUY4mOtvHByP1ePth2zU z-2{(vL8DP^wb<|dA0g+vU*Zmgwk#{P3=Wd&7% z(yV?BA(VQ$q7~>h{=Dx}n1+JGCD-?Ooz|3a<@B_pa+czBceZXpsC8ei5y94mjJ?}O zOcZfgbbOhrSK-KYYZ*|jQa9Z~_WZ~PXlAGFnge~j~sWaBC#0z`t7B&?2CM=VvaoyO9TehOSMH%x*1D4{c1kMU=u(mf@ z5i`o$1KL))8)f76Gbxr#pz~M(=^#$R>~7!~(V|A7+2c+3ya4-DO>}B{C$qyPn-Ibp zW>zXlEyLb!r*xhJ*mqcIyDd;3hxPZNbO}>s6ql_IJAj7N8Uh(e5Wm}ItI2N)vy;R& zt3QvtX0E_Jc`b3Sxu%S^Q}zrQZs%pDslL4H8*EQJwLgZ21O)Kae7k&Ya+hEAC}sS| zjP(xn5D=q1zWc^F^Dn0(3?S>?94?S-&iov0HE%5~oqG-^RC2D4WV@e^=YjiqSV4f( z>|oo|g}18)kkPr{e}5!6GTx#Xa@Y5G7Wlm^FRf`l4tPYsQIvLfeFD;*oCv!_McvU7 z;;Y7xpwIxKjgPL^t)FU`H)8s}#~4&e=^+|fs`tIcemDh@8uMhLfsW)jDgZCQX{wDx zOeD^BPqfnfeFclEc=`rMbH2-H02>Q{e4Q;C>ldIe2)Hk+6Kp7&pw=W-w5^k|Ud?vW z4&ByoFxh&#WAd{ixoEp!2k&!x8xQ58aGkZy(LxWJeZ>zE$&b0+_5^2Dym&d?g^BmsGxKPT$tz?`frGGioXG0QHuM*{7?mo(qf2Cw`(zY?va^_fL=W&a zLXMGcA}fKEL%?Rz7CJd|YIq~38spkR2B~CjTJ0`U#40(BD#4Y;+$unn&-?y<|dn4HLY$F58%A7H>WY`FM4wiYHT0f8 z@BPyUkE}*0rT~AZRnTHhFNbd&wkQy4Vap%A0;i!I7IB}hZy#jZjpzDmf{>gUsCn;5 z8J*w>+kmZJKT=}lQA4`O&n1~<=HZ!FcHDf5%8zlg=oIwyw;LhJN zv@he?hstfgKB?;fp#J&Mh#r7mr$5-q+_~dU?Ru*043#pZ%3{b~KFlu(OcRapRcb%w z$Hp4V>W8fzcC>zFtx=_XZ@Qfgy8A~LWd`}d^t;Y>`--k-WDWLdV3ub)SiWuyi+^ni z#?M0qTk8&Id(ttUg1EH=c+G8tO5w-Oeda}ba2jC>AFG@f@_~Og+sfOov z&+-dLqE$~OZhUMkVx|^t{qLD+Yh%ZQhE!Ig#3GRdK!*#k&-3&uu*wok_u?8%a!L(Y zO=Za1#`{rLbhOPP(b9%8piAkoClRBKj{iF^h>)C8Y;KtOyyFDub?K9((_)Xmy}K*3 z=c(5<;v}itFD}Pw5^mh-VU0@^O_pj#GIJc3ro#;9aBsGbjFWk%8ticFz=6{QAjzNF zDa~<4vLjAiJcC_sPPbcZu`r`l}KoL*h9=?j6I+dP{zMGLu!jpP;^cIb+Tn0cs^-Av*({dcNKO z(p!;H$oi32-4ml?DrOzMFyTa01VqO+1sbc%f;McaN6jqcRf-=+_7u1anVjR+et%uR zG7@~#++;yv*485KxcaUO^3|(QN6y3&0*kDv%lCMDg5WB(hSgs(Rjz*e9KjK$lB>-( z_Qq{Qh{sSAC)6HCxDf)89wQLu_-Y>W>{|3Mu*g0;Obr256>{muQLWJo+XHG! zpPmU1H=Se^vwfVr&fS2^N*Es;O*|_XVn1BP2pGEna*QDZ`ebWfs&V6Z25PMcMaF)l zwhXSBvL>-~|7FnB%qk<|?QO;6?y4LSToC~tGN{O^5t<6>0x+fV7aa63F z@gz$T=1moBk4h6i0r2xtRZsXz{zbEvNF_!^HO-z_?N@r4*$nZehpw}Vb^a81CzAQ>oM>Hf8YN;jK5~*}?NdVd zZZ^DyA3f88Io=VMSb<}~16fj*$B*^x4brg_ZMgc#i;FPft-rntPQ#`?Y%nnDm}sI0-_%Q=PGYsu^%%RZq)(*IM(1%`OZ{cOQN)) ztUp`YBi;IX-n=!8RYhWlZPU{>dZ;@-mVoP?Za7Y5wnH|7y}u56(1v~B>M4NaTEn-p zR8ste+TQGjvhL}E+(HFRXaWt12d1dN8lY~y-Qrk-vTcVzfaLESDB6Gd=+6n|j<^qi z*9$-i8nogDK*NREUC~o&Wl}R-5C)XfZj^zpMiw)~i6xeRhp9t6$29r01k6nR0KM&j ztQA4BPhMK~Ew<>4?lOvfJaI{W%v%k+kik#p`?I70C@IXHf4EbxM*Sn@dO3h({?|vM z_gRDQQ}*dqK(F|36@Mjo$^zBvNjb9tH6WjP;GJg~?)sX6x~%^}Q?dL@2FpL&()HNy zYUF-Da*^c}-M7nkkV^JzN;)Azx#KQZzj%X68gXtU!B6@&aM z_oEg?I8tPOp_4eIhh&~T=b!}!Qh{>Qy9Z2wRr2aui+*mXyucGs${$E*G|Z{{5{38C ztOzaP7duCH`>^9ZgLZxzFp|WpC!IDXdE|{xr#=k$a(a9|(NM1cWXF$(|B}$XwAKpC z)vC?VHFLi3RIP>PY@;t#Erb+!L=es0?d;*I^ZB;!^8ft!ZCUWba5cO!po}3D#y@+F z7w#`DOT1TlTU&9yo>zg6PBj22Wc?q!n~RNLF8S;T$FBDxw9;&)P^4vyi+!(-uFz=0 z-iV4j8>qQ@th5XBi5M;jsyMUous5B2oMs%O)e%`42D4!R2-#@ivZ(5?=cR< zFajN3j_$<(Ghw~3f*8}4C(GWWLm&$RRxMa;_w$g6-ENzVI)`s{4U)Hs0r#oNuzcejT7K#hGEpL>jX>Ublb6g1U^^hvH zis%3B1;L@2U~Q*5&1iF69d$;xqWk%*zADZ4d8%DDCt6U*deL|J;fuyd%afRznZNF+ zXQOAQ2a=!rr{%nN#C3$+i2l_r%xrZF{owU*?B4e7%3&XIesSR`)QuZz&~pVb?bYF? z2NR@e7!eTO1RG2hg5d&C|0AWO3eQ=fIAiLfgta zB-R)XO~oakrG|VsthF@gHQU?Ye}kRfOq*;N^ZIorxb=7}k zMpKupcf*|*hD4zO@(*C{N3%(8&6R-DGGiCtVY)xnuLD_2=7EC3iY{0a5No%W6(~UM zD~aaOpDF7Aho`jk^lNqf;F&vDCIM{+T%4UVQ&aB&9f^AWQCQPeG|>A}!4Hkka)>F& zQAXw&+cfC+sk*#ZjDJX%OiWC0@$%A87Ut&G@LV#JcGlM2kY|||X?txUZ4SIGQvBoH zMHrcw2+q^0Fai`CaKXFEC{r)e7#^9BFt_CmTUIz*8Ch~}9yk72q!i2y2?Rn`O^tqD zULF?@&n1V2+bf18<{^4KF<2}p;6@~%o5+dHLLjAfeKgykdsAu;fEtqokxh^!C!y)QpAUn zY4;?;2H76V&+({{sr@yd40yohZEkIu6>0bM_h&%24of(1uC~~gkzK&Pl(G!xiG4)@ zT(j=pu3n^SmY3inh+TNWHJG85C~}%Kw)wbWj;kHEwzL~ z1-8hz;YF+GpRjil!B%4--onf*4JKPDfTDkx`Ao)Il!A{dV1gR75zhi>2vKrJ>kxEX z(FBnz3HCSY$K$*|fP6Jr>sHlCl~0*4eM|kd_bU6ZY?i~wATX79g7eL6wx?FDN7gc!-_PuP!37`aCh+-QDU~Y&MuS0`v5U z&q{PEID5j=W`fhLQid9pN`;%mmOoCyy#ZfS_2J=R4`>kR4A7je`6=h%gB5S)8BkcZ zh~`vqC6olymS-cZN()JotSl^fK>m|=tys1?(cMgVhTnNczqix(E9W`r*`9)H)!`20(P$L~ zg&^Q^=0h6#T%1u>$Hj#Jj+8ka9ZD0ElYZi$*hu*sg6#6EB5#x`hV5bIDZmL47#5~w zZ@*wC`OC@1UJ9iEq6tp0ALof_UHk(S6GP3&;^13^knBKz5jGE+d#f86ea|%g_!Tx) zX9%GlH__2O>RIyj*pF*3FatFk`FfTD$;sd5p@q#Ps!h2Go!|KM=6(7c)DRyX-C;S{ zY!0R6-@_JY|aLreop6>lO z;B+NrE-<7JUA_Fl3QV~xr_MK;Bt@xns^baZZX9Wb(Y z&8;U5owGJ<2)nbaGrP+1`4!}kEJxwiOj5rdS?vE5i=PaJ6vPyHnwRnqI#lmEYQk%P zH>!cG;{UuN_{aW`Bi}d?3iAWL{uyTY$4wDnEh1n0Zw&ssKRU=a{_A^&Z#;T@C&sg6 zfV-fdDefPumZAIA1_f=C-#V*~NZx(kn_W9H^6nY(w{(xore|x?f3q?DGImIR!DMc% zXUyRU3#1cp>8g;evP%t(pAJhZeVG_B4~o{g=HlXZh~@A&0hr>mORYV< z!&1KoK4f8;XZ-SXPN?ci?yJic5GNv^BOcH{t6{h(SmEhmN__3yxqkHWMPbtkgK!Bg z&vDnP-hT3pf--6K`hD-1$8tC0QGtcn^Gs)%!ui+weM|qzteEBvyjW8?Fe7O695tHAD{^IX19|ESr=e7QO&3OKGHQql5fiHxdsJp)Z zp7J5!q4Za`|K1?|OXUCEQ>-G|+h4C*~JQ#yp% z+wN{L-rH6dk#6n4fZrb>3C^st_E*VT{tq5Jpw&31oK#hfQ;j=X#tutYDzFmQg2^iH z$f>$1tn4pj#Hq(E!ApERr%Te7SZ&R}<>ZJK^(c~=BIb}7nV4FpI{iX#NFJ?kTaDTh zT=IR=s)J>19@nV<3{$Mqeq_TVE+$P*PVWEp>sJK*_iCwJm?>>hpSAU`qM?gnN@2}B z3vCSe#RIWe$B5KO5l_pQp4`tN;T{zOb@E&Lo3KZvWoU5Yscqt7&7e$|qwEt++6MI+ zO-wTGuRen0KFwx_QDP@**;BdQZe6Xz5d+EBL#7oP)lXV)ny=&HP4>;;yV)@n>^){x z>ae0eU8V>Q#eivHbIE7i_7hX8y1JI3orO0|5IhX^V)oR+ZF6Rp(!hSP_6}Hy+L}b_ zbBC--kCUrI$`S`lvF2s6Uv_3;zC}k;GzD^#CN`NO$qPM06dLDFghhMtR#EmLgfm7) zhEHubn2Xde?pbe+n*53O+CEsy;dIz!B_JT+oR}WTQun^$O_uHoCx4&BXBWDiWIi)H zOTcLj!Nhbl7_M>W3JxJ+U)WgbK0naMiLEHTDl4lnpDK@!n^56Cub@1(b*|W(5Ec;` zDvXa^Tnd`abHIQ0?B2TqrACc<{13l7p7_jr4qzQwJKA*i_eamq2UXYBGU~N6($djA z-(iq(*wvu6h`qXUKiw1fo%N&F_{jFaeE3_74+>$_NJj^O84*!yTdT|Ng^9s1)hy|o zH*b(h_y+PujQ*HbRM*uEd%Y7NCf>fVSV)Duro_Wk^|akwQc+Wjs;LAUv@IhLB{VcN z2@A8cv&T=j&3}G%RW9SSHs17bu7t5FO(J#xa*jZh9`6}wJZcQkzI2Qpb20GXq@hXd zPpo``O(eQC)@X1@tJ#&cx2=3iT9`X4E;k%YZ8nlWz+lq5Y5^XxwcYK_{KA5?f&%Mp zv5Ie)40?Koeh;15#ujwbYT#r`c6-{%``b4mT3Xump)w+i>2jr+PPXer>h_%%>~Byd zn_*e5WX8U^!JU#JoqdEnJZ6iF5dk4$tsNEN>2_H%-)j{T8wsxl<*O?QJ|zCMnmM*r z^7k!b!L9VMHem}mN;D#(Yv!0rax*hClVl^5PUXJut(4e%F^^td9d&KE+}F4wP zpK)<ozyv829x*!a%2FU>KaQ{&tQW5gBo?Z%w|ahJ1NORycN(kS|?F z%;Weql2UqMb@#grx>f6kwnvX=jI1R!Gy zgodoZqYH*i?KXz#-g#L<=lF(`GZG$=q_t84LX=0ow01-7 z7LB>4yH!ndV|gXHq0Y`kRDoM#frFYzogH*2Zeg}HktJvF2_Bw|q&aO3m)aFKqC|gM z+DBg|nb#+<=bOz^r=Ed9U``HYfl~46@dgX4)m#*a^1A6tOrBSoAng3AD5GF{iCV;t z$HEfApS&~e^dmXCqx!%}*T5hTo|2Hzliq}@tTL8=h=tYkRlLZsJzya&u9>0fN~x%} z8dsK+W3)`{gg;;ocsHqM^b9dwW09JkrKJe^-YW2%kIv^fYL&-BWJc-Cy2o+h?{r-k zl#B5*wmuB(y8ef842p?G2_wuJs~2pic5+2 zJ6PHq#yVigt3Ty*xq1!pd5G~YOHSX=u=A&ne_%jBnm&ra>Go6*2(;J9Ti@g26Irrz zJ&T2fB7XcxgDXe!TbY@K=x2x&s?~fKJCjD%f%PalySnI^nQ5+EtmJLDQPPozEH5kA z+S+p3r2lG6V69=otFPyVmSSnw$WlVkaj*R71)7p(dX*>LK8e-6-H?c`$cs1%Vl!Ly zol=kz5<;G>b$AIj?;BH`{zQ(hKFN&SFvSxNu)VR+?a=ER5=ZhP1@iLpR8$mrOS3Z* zPSIalqNu8JfzS?fVrnO89-jIdTu!@9VouE`jmXTk62CN+Tesw%J(5a}E@0>7ky>2N zA2*r0%~H$KAJx48Tb2WsM=~vNnA_#k5>PLxcE>+kG)f@z%LHBu!7G+IwvWmr5~XD-Ta`DnxA>7*y*= z_s^djIPnFk#=#$D_OTj%jxiogIKANaa0{>E2|L;1_#*9}6H9rGILTA05zhx!65tq| z@1^44P$1Uwj%gj!k-gUeEV*VdTBn){dGx$bGNGKh)`V5C8B*)*s1@B8m z!yM9mM2Xv=){SNfTC|!}5boS#Le_V(QxzA9)Ix&FpFVl}*0^}!3CZBkfG~#o#Ls5RoE#%#Q-0;gthTo0afyjGhodHoON$%hP-u(4l)p&GM``iJ^&x%x zy*b4u%?zdtgI-+3I0_c=L+0meR+g6Um6WnQRh+@sMQ#uiLn5AGb0x&(!tp#;&}wRG5Z-(&EZD%Uu_IgIbab>B!}+FOC5v1`uy{LYxn`xs z^cQyJ-lZ^s?|FG|1#ZjJddelJp?n}u9NO9uul`` z6XtP=nI@Ol!z-J{ZF)IJz-5XI^6tdszUoz33_4Gbe zvJ-vhU;k`K;2EEJ%%>7Qb(*!AvIhbe&4MzQ=N0mW%Z2l$vocLnPx1JuLWqwKU*ukc ze|)@nxLcocQi9DxIu#dZOG^Ng<*!0rqivruC)pLlY8YBBBj%$+~(&#!%=AY|OT(uyJeZgvj~j#K z()0Oe3Qgp{4x*HqjNqajqW_6jdp|VP9S)N07vSLGmjjPGG zila{I)OxY~EhADYF2|<47+Jx#>(SBC#a@#G#C~^M#?^HJ?`2HPiWib{1k+76nhoW- z&49a)14k4-uRY_Sq}yh8v{*pIvu6(6~bz8u;2oF=5b9(mz?)H7+$tpyob5cTT9TV=>-; z=ff(=_&#HZ(SBV=35p0SQg>urX>@xYU6OxwdAcLzszx}Tk#0Pmjgj}(1hFuz7#Kk1 ziEG!NdhJdLTgVFX6+HCtz)&VXJ2`oI?#_tE@NM14&CLzP+}r}S#vT>KiDO!a*y{Z2 zEQh@z3_J9dww|c+-ud_UA3f%MXTATR_H13`LtywL#k^d;d-u41j%;vxAZWWnNxE8E zzQ|^XE-ox!HaEY&o^0BCBI*-5RB1tEZk{gyZ(#SBQwctp%L~m%Sf}zge3X)UdFcAw zLapiz52b(g1n2cdn;(Wj8zMv_C?Hc`RKWfL_jRlQmGl4D1>V#1jKhf|y;yW%b2VQ( z?vt2mL9JGWTK_~z#zYzAk2e1>9S|JONN0^#rb~Oaa<@EReq+kYexq-+W<7EQJW+4F zc$W8Qn^i+2dN%8ONT9*oOseztkUxz_Y4DQ@2M~sC5c*8Y)GFxR({&HR_zoC%rYiG} zN>Od|%?Q-yP~Lo4*#*F2PoMkyEC(QC!3WhtXktipl~Rz?+h zZHEeM-x|3Ew}n+ZEujfN&ZMuWn{HopeGMHca2lk>GcKeVW)KoI44&s-RHIGNiVn+{ z5EC=ljFdS#8P}eNDNItu7ATWD@4&`Y_qPTorh8p+(|<(VWG~0*@i=blfm??d&&?1C zG&!ClDuuG-?z)$j7QAZbpVrGWM-04O-bfw=A7ukRh$9w$TGcY|M#gc|$XgV-^hT3H ziHj5oMckgx?SK>}NUK^J#aDNKvfhR0?#X1U#gD3O^p^#V>9#(NHmLt>SZG`s~XyJ0tGt+{|Yqc*vXZ@VZZgr?K#H%Q*MpGeYmrzbC zn#+Fu(b4M7H^B^%`r~1A_k$I4QjhJIu4fx!gIcpL=L?q?=SycUTRR*!jyAdjSOU-N zkE<7tt-AP4wyz5EQ`NJe&kLXkCwqI^vo$yfTl+~e0@u$)MMbZ-8a*ycO=0=m)HWTj zs~JQ=b!!akiM3nvK}ARJ$}tEMSC+#w5F=ry9oBNHY;XVE+S*paTBS4b>m^&l)XQ(V z0=GAHgx=8wN?TRQSeS;ZZe`AAvsibZaTjy611Kn4XNhrf_*d%Di(Q?Tlclr2v!F9Y zxb8EiD>aH8ot;NJRd9V1gO2UVvh``GlW*5U`_r{v27!*Dp+IOO!mnM(VB}tw44Qrd ztI4z8SO$*sjcMhJj}h8l*U?YOMexn-?CqCFWCR*evx?$|)@IUD${(KBmz!ko z)gz*#DH!UHY03JoegFXDupK*0A))bDOxK)Ftz2jQ&rde~CWoyt5jq*E?&N=vmw<=n z^Jz%Fx0vfW@YU&33i;i-@%fx(dExJZZpmL?cx{dC7_$=2x!Z9QvS6rJ#x%$y&fvWS z%+9ZGNa_v{#{{2^493^v^uoi(PulFfl2}qJEw02Q>JBuvK&8X9TkN*KHxXjvG~0$a zNu+M@1Fy#4j@;8q<@Xs#c4bVvWxUZU?VFG587|D{ovzwj+(nJtn8`!Q5S5wVYl@A1 zD_G1P>jZa6y*v8z{zqH}Eu~d_igCqcGZ_hqwVO*)P`cLz1O^uDbL#i>_v>rV^Cz%d zcNx1ab`G}(xA9%!*eV~ae?>z`Tpfz5I&b4F?bjz z!(-&J=X@T1=@l&5Qf^`6+5wt z(PhA68m|_KNIjQPuclC*kfo~ZAfQ(0c=YXXIGK}^)6H4aZFqFF!LO!eO+*it&m^~sQLXL7J>R-?+9SI$cIw{9}dm`kbr-aFdR=e`6fyC|59zz~?+hLXY+y@X3 zt!-?wMbCE4XX{})x3v{SaVITZ$LmAM3{8mV=;$mlQD{lg#PSi5k=O#a%y{2PH4#S) zb|(dhy{QWS4QRvrE%u^|!(JH^SS`+owwupv9Ss(m*X0RTQgU+KbvJDS`)OB@r!A2P=z77c|M@qgXU^agg`{6?z zo0+38Qe&7EI`i;IjqQqBmdgyLhn(0Ah%;-r>!9Giaq@nEjys$m&5-JG`jk5Q`+FahC+;`*ny#*B?u!R&Q5C6I z6<@)Lph)w3@bH&DqP9A>FQ+Oj~E{$vBA+PA*wc&hczs7sw8vhJGVP(BKZ=q^%^i1l^+8`YBMPEN`l7Fz0W z-{wKeO%2ZDmP}-19_U<-?YJMEIQ2PShA^*H?w=a+JRu{KDKpes$@Z$db3=jiKi9__ zgIhq@<)a<{E-pW;+kdO<{7kb^iW55LMOq3UTZ|(EYh0GX|d>(~7Bi zhpu#;e3f_aD3yxTDWLtIrrPAQRZ?gwoYZIMDZ3S^N4df@>~Vzx&6+V zFVcOKb)OBr=o7c#QHBC)N^d9hHnyk1s<)l{&G)hP{|I6cn6t3aJ&qns70@=+9xv9U zdAz$7iF|g)02nixo0}gunXwZ3co^cYa-7B!c(yZf)Rhd@x7$?tV0WPl=%jGk$Q{`2 zMq~EED=Qd(Byj3}Z#gYew?dYK0Hp2VC3?@r@Vjm%@pbz&=C?d$3OO{n$Gp+Ci<7x* zQe`UR#Ypv6Jwef=@~a4RG%D3=@t(BuBzAUo$rM{GbgyflWFALQenW)Ebsrbg`wo&e z*`AozTuOu*Qql495_`WPCB-4N<2mWhKfJXbGgrE*`;Lm;IRw=vOF_V~XE-iIeq1a{ z3^JLwKXKf{T>kwt_L6WS!iR(dl)EMNxZz{}BVr#gmUEToYQ3@Z;jCO6I z_!vzd*0ULOz<9J8>*+6k6q9JFGLU#6s+^jbh@R?>U@BoMIo{Pje@~lMCScWg;T2~( zdX9&IMaS;m{;9CA=-~Lc83tR)jw)&-=FxIqJ3l|bo>63t8pGGqTjcb-daYUOxH@T+ zvr#pe%#)gy(G?gN*am|UXls*6r|=qB@8-!tL4pYX>fQ#))2w5^>$%>)M*`6TG^U}X zd?M417N*wGFqtxY7jCCh(VUT|PyUGA8g$P!T>dI8W#%kiKH0M84kh8yWwh56BZ!JQ z8tNj|n<~%Ybe@00VlMs*%*n;J`gBq%q(M`_M?~>`T9B& zFK@!U$}w`luw@Q^-s{^6GY;#$%)oke)(1bA)sW-kRf+lCzbO^D$DbZ6Wb^SwW6j+L zc*Q^&AMFN~r|l=brOr#=>kbvX)g zny7W)VKMA`&CT8Uf(}IHE*Q+0&+W9-uFLYek}}mj3Dg73OGRgQ$5}O;kOJJv`7p2x zN88Ipe1sOtE5mp4`u+PZmmL_#-63{s*L`+_jqSA+euAYL8TxTd`ft>$EZ1(eQd>HL zUhi#L#n}J_wI)q3K!Jhi4drz-Ts3PC1(DZ8|?S zr`fCP>dIVtaUq={L~T5K1M`4nll0n=LOVQivE9UexJJd5&711MpBNl0spWdXwz#;6 zgwN^>(e^wcFd9f&su-V}zpBw`yxJ^N!{Ad+Fce<7SWRRAApRP7NvC@;i~jQ+cjt03KvaNeMXT z#@(anRyBw|h^~-uLkt=AskMg0pjm7wnH`>~t z?^9)^rJt|99bB>A8g(4;z)acBBonB=Gn05O?Jr+0Yus8t*CHP;hl{4X ze!Xm4(?+bXzvO(De6|6%dPKrwZ?GL#cX53tjJTcQzd2`_syxUsi=BHYm}VW$czAmHS$=y@tnRDX1)AqImb4UyES1BS*uidYuCMB z;pd30z4ci$h-TgK>J9RS`L#U{Fs>1pKa~fO+^>dmmY0o@;`r)*?bJGLnf(|GsU*s^s#90A(GjrU*V(P} zLL=)>=-*&5`e{smR%5qjJX6i&=vaB8IXXQjh&9_)x)O9@)B*qQ8AGq$?r}D&4)4JI z@JLsP!=mqVH-6^%I69u7^La~G_rO4BU*F>pkv0&8-LDQPU%&1=8kQIoJn%2cNu?AJ zxU=ttT?_B+RjsB@>gF*9_=X zT&_>50=@?>_kcK#iHXU~$tg1)g1>(K`tXD!mBnz|_y%Ez zYGPvITOi=H@wmA$y^@H{^qh{b;w9}i+FrvM(lz32X{Za0%q1#3rF%P!f8~TDyUgK8 z>B9$l7Pr$vbp$uz*RSp*)DA0Qh1ltphey%SO*#*`QOYb2MFZ3Kj%viXl|9)su$=93 zl~KYVwH!P7-I+TKVB{+G1j>VOg3KT1v7BF2WO&_r5_4Aj-$!v8sc^%C;4-M?3wX8+ zHif6AhWYs1C*mkt`LoafI`1M$eu05_33GGW-QC?n_&%9v==M^o*R6Vzr_-)^O?59k{SR<_^-ahm6TI!IEqAs98KW)8c=oy+9y- znVp4n+-5i3zH?n3LRlC1C6MZV^%m4e7yB9U-`Bk1p{6|W z#<9;V zwm*32g>g6y091&qtSs-rdB{S4$6yMtJLe;9cuX)cTas_nO-l;jrSl0a_SmUBiI8Wg zNIljTDl9gI#Xk`toy`60xqZ?dxxc+A>FCH_G+n;>VgErW>Dzi9mqVcilJ1lS*U@TA zMQR+tajp)p^hze4MlII8xU;d7T;lVi!^7ppjwh!(Jk9CC5*zD#U9}E0L&lbcGx_CO z-$POvD|>2|>zsBT=xk5OBDyU2Zd=RjHwe9J+h=bYgul$hm1LLb;e|(nJPCROI(Z_8qEu`Kpf+%)~W7Wkabmet6CMMZY$IfakiW9X2CTIooO0@EZ zTORYBv-)8Yea*>1frRlMGWNz4L+0BLB3UgqJHR#K1orSwcQKZ;VpGS*V?j>}y7jlz z`kFMD+dzcSYB$KQxyw{p>F9nwBnha*&3gB$jKV&1T3XZFpE3bGpAA+OmQ*$(({HGD z3S1`hghws}n4GWbGI1?4ivK zUm&2)DQ^{yjmn-aQ^o?()NXNEj5s+7633`ZOmlM)3!q(W`)%aBJYNi0hA7PGwNYQ3 zn24)u&E>Oa&p2%spVN7`<8zrhN1H^`HkAjKqgKf#Dy%HY7#?^*2Vc;#2Fnz;>QShg6SuRYxvhVgZkk7G;t3jw5+0nf{QDDVuC1)J|L9-65nUhB?8o4k8aO8 z&2UzyTcCVeS}7WJxGi8~bJ@Or1W*;4oBd4I9W6e$!=b|#?`@itLbciID0sI4axLtQMVCvbt=F97; zD*ZM;SQ1uab6#Z5WTgWND5Bzyt~IWvD)gJ1J-_#Ak%WeZ0Hm0L`ITG~-OHEZpvL{F zly{;H!6Cy_UyRQIE{}i{aVarC6o>zFi4tf9cT{66wfwXzjZ0B@I0r)bVEr5DK-NV| zfCwfeEyI`GwsYpI;GrPBrrsC|*%E-)@U-1Av9a4OD(@_jmZtB1JVbkK{6N;tkPt%& z7x(j;VPsO2pKlfyVaQw43f`w5Mx{MHk!osOJ{vBlv9q=Gw0;=UFa+*V3@eAK)s=TP z$Rdq16t4; zerxNlz5zWU&+_W(!KylRq|QkOA`(hCz#zczc{fbpC(P8w&W<82!dud0isbqlU<0pN zSb{*uyEr-#2zsFnSRG{$?sY$~HUx;kwl&r_si>&t0U^eQKzU;lnGngIcgb#Jx-A4q zV0Ct@rN*~s5eX4JQx1Lw#h|KUI_b_CLK@^dW0lXA)ccc$^mtw1x%Ybdi!$z$bOoD) z>8hRiyquKgkup?)t9^11oSH{Q9I&KgeVom(|^`4ygY#`L4!D6yr3XZorsGSC%%Nq&7x#$We z==PmQ@4L{Y2hxLbdTJ|S&l`i6muDpNfE&uN(HFh@73Gv{If#KD)$PC?&7cQSo5XD!7JeZv1QZc6eP4}Cek1ld%#{KZ}E*jzy?qj9yH?@;SNICEKH)ddPm)q_FtJ9b=23FwcUW4SChN4roT z&xq>jJtOxEYZ>l&raoO7Hso^SYcyG7$6;f05L{>W3e?7#*|-B4<|Ek^ExZeW4LLmpk25J%0%W@G=P1*JQO?4f%Mlqq61lEPMW! zsR@|$s3dS1mOw5<9Mij}REC9xwJ=FbhgbtZVr^g+fDZ*g#3d<^-ZC%{3dE2~by`u> zl6H7vV%@=nT$t$ScGtCN@;Ut30=qS9*(Dy+(ttj}=Q*{!7T<(0G+w!fq@ZXiPQy-J zqsPolIF{6+UDjy$gdx3|qJt>7(DZzJ>FHPu1AbVq$~+iy1?Z!p9Xpk08N1<IU3m3$0OaV;Ywe*gM*stc&CeM-EuD-7nr=U!DPd-8~5j zbigkmrFgoU#xJ=ZZ+CLQJp-Xu5`bj93&S?MRUBxV$6sKxv(Y%W^eek{U3V=5z&m(( zXI#$1QO=K`z7Kgd&B7zO)!}ko{~}wtLbO}pvK9tcS)63s{z>*Y%-FPZc>&F6g#25z7NPn9RgGTDVyj%#LzSDNjtK>Ah8LT^}MZDJvsq zU_}l(DvJ@-6&Dx{zo=o)=ilt9xVqqbtr%x#_Z+%x^d2%{` z|LovT8sSlijbya<$FTT`{x3$FlU zwOPOrjk@i1?n#e=Nxa-}HrLsebHyMnw8Oa|h~u4K)g7AVs}g|rZF!T{L^WE8XQGN6c8Nre9e!GzlG z)LKB!y4;O*r^_jxt=k_@Mc=AZc?f#+-(MdzmF!ogKCbjS>OTXz;7&Idc(x*rOvIDU z@aQZGa=xIM8D4^Wbf!htxn*ya##U8SVcQo|cgk=^5pAi*lhWJqx4*yF1+Zsq=Iqay z8;*sP*jxGr!I6nWth*Xjk}-RgsX>7Z+G{pQs@Dx0;KG2)c);iQ;6N9I;S-Hkp0M)n zBGDR>o;KPIC@*GBvSbjCPK9>&J_NSgQJIBo9TF=ltp=w&vxxW4`oJYsNsvfkOOK$aTPQ8bP6MAL0r3*IxB zR7Nek`GnBcSkeCeKBHQ~i46&bW+Soq9)APmS5*}yH+Aip2`|CQh=OYh&ib}^F*IK8&?}>>-5b9{OJL#&ZaAe$% zfK+Wa2+$#Qg{A6@56mWUdH4bJ1GI@J8+WLX{-yN2vz@iWl}{R)8pkba-F7m>0`Il7 zNJ&Y3*9;8|N=#v1oS=>Bjj_-`ZTgyHgsoJBzykfbafRC5PYet)j(byWH`gcufuSuU zz1Z?2t$SP`&GZAx158l>$Z39e)epcX{1{-FJqYfO?vBg>nQA1qsrs>00;?_%ac{%D zepFXG1C6sXzJfMrT~?*ko%esD96L?W^pdl%9K}?J0_pvo+_JIR1B{a3van!;5OIv9 zHhH#*fQlj{D~kdM43KxH2mk!^F`H@njyGrqt5qEOEe}E4*h{EC@Rwd)yeN@E#piP%75&1-G^{ zRYAdfg|;@3Le9n(JyxWCx6xbMpw=rrH~_Q;s4g$wSB4)kF(P%27ADIR0e2$$l<=Qq z7W0dX_q?l|?A$%n^^B~#vLs?pOrq!oZ7v+RNi=JbpOAX`&L6crUtU|<*|}Q;KnMVlW6pcEPVVa4o*j_wpWhSG`s!!#1}AWadpu3YR-Ad0n`qU zfHof}XF=Nr0mdnS1$+VWNu`@QwA2{>hvZKYr#n7M1uIQ3vtOl^hQpbGK(PzsB>TG$ zjRS&lXZ(HrhN?^CYrZIon^H?lheFIJemw<)BX49HnW}i-yovesi}C7e3LC!~=$6!3 zfW{R9)D9x1rujD-EFpdc-1 zPmW3e^q)&Ejn^?AG@`|qs5@Xt*W=(8I91k&Q8DXNXmuj9z1Vgq!JEm zGA^!3@8tJd&x_3W=5@49$nrnh=)enI?ED_Ty&Y)EipGh2Bh^0FXz21cb^>)`IqXnS z;(=WU*fg;W{==mP62rs8oX-1%^t`PcgbJAL}CdcfEXIyjn%Y)eh?K{ zAS46>xWr4a(SS0OQE%DWr`dD983|Ey)nQj3^6B84g_ZK5fp2zBLPYfZv@teoS#^xvH8r(K}(?&LcbQC6|NVU`I8wBJ~i<_Hh zX;fkA3*6=w7B-+lFVXLsth7K0!li3zozY0u?si292npq-M|d09}JqtJ&I+ zKYtkCNGHAc((rEzSPV5N=Q;bSyAVvsmfm+NpChfWcdtn8Vw0>TyPqxzMXRr^E!k1H zASH~D?HRD?Kq{8uUP?oCbv5Ho{O!|cwy0Q6cZ#UqegPVqpxkw19|nAJ%U+=WrshsS zA*+Ya*YE$buK$j!fB#VfvEh@b7)f%V)Z4Y(HR!QE*<=G$`bih!{CxdPSX4AJGE#6P zTWclea;n12IZDMUEuYuYck82s#GPkmW@iuAyVxZq5to#fXR00<<|^ddPQL>023l#V zDopBU07dXB7@yx*QPkBTBgGxyi+ls(xJps^-~7Djs24Tgn0|43aBxtlUG)XkDNM9T zDKaAB!!)}EzJO=aO&n-&6{y>gkO8ui?zE@X-r0HB&jH8A!xOc&WyX#13(BN;^Cmnt zHYg}aBA#o`yQR`@Z6IT0<5y{8$#++PVFF@0j(J7vy7JGTPqhwPYL7Pmp^6HpmQ=$r`bsn|5s~Q8YX1oo#My#Au$%Qqvinuk zRhb+%u@SP*;a(j614zj|%fdrwXF#b_Zjp1vG0l-kb0LzT-T~@}ju&@B0^xluCs6OzD z4amI^APRU25}bc}*LpIq3!%|kCtxQQfyOI(pGHVn`27&t(b3wqkcLKm*J`AfqIx>?1`feb9LMi;Nss`m7zb+(O-%gOimtSgXN}Fs7g#Se{WNn0O$i z!EF-Q15CNzsSd$-Az{+UP!lK%^hl?F$^neT5zB|XCAqr##mF%(5bv7a#&jIi94t7jiqNfNU1xKLH@fe0X)fKYOWE*#Vq~*jA~%H zU6#^pt*xwtCnWd*{bkJ{_2BQ{?+W@mT3WOYGGNRsEEnq;GI9LZilEmQlM?F~8>npk zdC0}ZWz3quJn}$1<|P9I84u628s8koJlsq9ZqEV8FrPV0eS;gE4%on$Gy3>(L5P^b9lK4`hu>n(>9G-+NZymvv zl+mh@738DBqJmiM4X$~LwTRfRnVI_G>oFMJI|{XmLkhqLrSn>5Z2^!iznlaKlY|$b zJ}wpaE)Uo3x!JAe#8r&(on)e#{~Na!FNmFQEbi#)S{iTk@W9K^05eqwCl-0@6Y3Y- zJxlOB^4VG^MeEF$AWs$cNqU}phI%FfY7c~t$p3kh9$ALALolPMR6s#bKcJHcD!j!9 z7k^8WMQQSuzrpsyqoHPk6=_=J ze6^ImpPjz4tzAVsp2di9pYhBDP7%BRw{I#Ckfwn<0{l(tgC01|4n2uDxqG1d)mtV~ z2)dmFAs71_8lIr#%vOsS+!#()Q%Rs%G_4@CvqRTcDEhlsAIVZgmLI>?w0QO#oJqm; z6fgD-kf%d+FciVP9UL%C@NnwsTB^c3{`MM=Y*2Dfeq9}xD-e?;Q~Y8`S4v!5U;fHY znbR2b>OZSs%5L$TsZOe@sQo4}{TnTxq&JQt20R?@U4kTIyZfVLZ1Tf@S^%CY6O*?m zn#lhh>J*@ca@G+v^tQx(Qh-+bRK}vr{K@c${8rtg|BSf%qylrdLT$xq(XL$0wtR|k zg~hu0$wN$HwGAet!IX?V2*8k}_4@bGHoosEHq{XNY;G1lBx>wyczkTrI!%Iw3PN7>* zpY>&UG!TV-s>gZ(s#jU^u6uumb1=Yg(*vOYArB^DNf|4e0tvwy)cr*QYx_URkGFV! zcn{28tZwa56Tbx_V5=yz|7ooA_0*=3foXeZQ$S<(RU0=VF}48icr}4ag_a*=BFQG{ zv587c*Q*@|1&Wdiv+*MUS>4|sOSC#V<+1uHmv;wm13YA5!Jlk7kdkbvpJR@l6PoVP zvAw-LQEft!AriVWyrOe`O2XrK*nI!YW-v3bFP3ZH^pDsWEMx$;%?R#jZ*Ol#T3TAq5jq;$T}fsx-GD1R`{QbXw zZvmNa8zA&ao%b8jMt(dv`Oj{n(Q5D-sPTI~kYIpx>Vc01Ixa1;&gLlP^PDEv6GA!p z5#x;!ktPdR{_Xlm4hMHKW?EmvvwDRk)i6yK6@wVD1Dm zDtwFf-@ZH9h|&5aQvfS9S$czeQ|VnW{-MT|E(-3c-JBhg_`AFNr^}IHbxlplI<(`n zp&=MvUqRT>Oe;rJRIou%4^ScP?d{J9T$26CJbxhFzqDKbqwB+(oRoCFH7E>N-V$?@ z3zJvqo2Y-Umn&Fx{MEJ2aaSYq^k%0}D<7b{!}o_Zn{#fCTQRGSsu&bfrL` zxYUD!&1x>VZjV$ZmH$4cD{DZuRD<)z3ZCvRct3QImYb0k7 zqA@!|OXNp>>j}3pb&$nEfiWEC5)BGXmD+Wtzd;8+OSO2|KEeIk- zgLFzvo&k;%Thx07{8 z)l@wKnDeQ86Dzp5&z}k_AU}T~KQdZ>_?zY6qx=Z%$RX7pc}1TzMd2v(pk!Hnh1}@& zTKIC&gOpt7j5OQd70oG40^WfuQ<^HF{ezb$Q?aE-+ehx;zd0B+vJCQOjJLJ5q3f04 z9~_+h9N&UK*vwqtzkWteznikJI+)-9dHNWBRCqrv;OzLFM*V`DYXc@Y(r)QVhM^P# z$dkP8aYrdCw0{2nc=p_Mr2OtbE>n<6Nh{J|ru*x%#E^Hd!qY`CWB>=l>q(q?)bY{c zQ-iBiE}QA=`{~_> ztZ&|*p+g{&y!-flI1!fe_s1Tl8p>Dye3aTs?*2WXkT}xq-#@;h>017OKQyVl^!|%{ zG20Q z5dBHJSO1(Q6dlsd$ET>!t(K`ZP^#jQH#GT)!h}wV?BB&Q+0WK>&8OPS^L}M16n}Z6 z0r3Va#2yH`m5o$VpEdzraQ&8Wrq ztD|fMY9`lX6`zftKXo5rT7DVI=)&b{D7U~-7^_u=Y6ZFSV?3RQ3pvwiT}2D)(J-tG z8J?1dh^^d&UUkjyfjORO=h?6z=p{%w`^EBPdyOnLzc-S(9ekaV5zc^H5<9@LKU$?L zw}fF*D^7MjeesXEw-mtinSje7GTdF>rQ5^v^z>Av&M|u53E+Ha(R1^@i|^-e(7PUta{_rOB>6j*5*=4v|o%7o??kk?&?6 zCWk;;+sM6YW@}G{mPFp;|3A#Vc{G=8+cx}bA{1pFGL|xBs%S7P z6^cYuqKv6flrd8XDMLsqQ<5p9GKCD0DMKXlm?`r-Wcs$Vx}W#`<5}xl&-<-+tehGX z+m-j5*KI+s4}uMv{Iw@C=HzA32+PLpd(>XgR>Z}|Ua9CcyGqOau)pSmf=*K?%Dszb zz(wUQRU2)Tp#EZ=99gQr-G${th%N6TM)PWWB0DMSVk3vnhe2Nj?PvS;?GrPtUfO)^ zH+o&zQByJ9S4ckh{QJ2x(_z}S9a5H^pXkgZ966k~vKiJ!aTm>>3wE3zi?(S0$SWMT z{IKL)op^h$8P)GO3NgO5?qz?`I~BL1Jo+xZxRm2uvac%Qn0meGL~|Tf^tY?3*W&nE z_Wz`?ljh_^$x`=JNF~YDmq|n+<{MXmY*cZLnZ~2YgKyK*OZuxWZtZ9Vy(1+hwWTA+ zah_xMLl>r+{f><5R!^ZmMN~JNc5CnOrnd$q0viuFkztM zbgsQ9Oxk%r#-)sFqlDQ*DyE$%>K4>_+hrI%lAF!R#ml=X?lfoVIC;@_j!!g5m6=}G zgio)l+b4eW_t#q^6lM1_CLpE@lokPk_=V19+jUy%H zwj6OfRnHEPPu;1i8GhU;ly%-Ga$oG&x(y0%Z~as&qKGA@;plR4*-`Ah{qxp}s_P>X0kj|#ry0T+DPm+!&a5Lok_%ktwQ}q4UkxuL~II)YiSlS!B zWC@$)!=e|5-hWNh-$mOE>jQ}TtqwDG+kuj}xmUPoeQH-q#uTPP!@_((_ZX~taTXL7 zu4_orF8z=Yl*TKW4Lo|(Zb9$v(^>b79bvB{}4$9m< zmc4sjjAe1h#zrYLMdY&DSZ)L;Y==A!^VSS8NBiMfhuo#HqX3K14zoi~Wt=E&Mwc6| z9x?779o_1gv>qf)mh}L&MQ8S-3+dOQ9UigrI#-`abs`lADtd8ob8lZ;>f|OBsL7fu z1nqXa%4&2lqrjid1vCBmwpFaa%1PcX+9lCz_-o0l1o9JKLfkTb=`{MThkgnQo&ez_vT-n zGzMu+BYk@reY^X#D!Kf;XnsD*IJ?6~RdeLS@-yk_Ei(?%5|+)u)0u%ub0n_EY@NZn zmoC+2T3Rk=UD^5l+5rj6mIvBYy6NPuoRT+SE4?(?W?f@A^qu8q&8e>Rk1qMJ_nHRv z$8yQK$a?IhK8BeiRX=imhK9uh+f7KK@ZZ^cxZ*%Ih>(IK5;?X^#a3)u9#lBvp z^$F&*pVE%P5|uMqcKno~!pFNK%l0u^Rx+nwcocrbMU466C7uwuq`e*qLZwH|PG^%++!Se$k-R9i@8 zK77ObZh~#+qy=>>n}z}TPlKUXIXiud*woV)w4}8=igsOk%>X>@)Q>qJBw=LFYD7E z5%B4>Q;z=ZDpb^Y*UJ_(L`HIPkv$Qs;c@>y_u<2=+Y-#7g=DzO>94553eD2$@J2zCO{C=Sa}%X;uwZU)L_LThB&rIKyT* z(c|0hQL|~|#;(3la_(21avRAHloI7;M!!OfW>^ngL$+CNH(Ao5llF4NKWwSD-oIB%!ySoR4lZ^8Q zhLbJVcUHviHFW-MFD-m2_hDBQ<6wIdC(4`MSoXbUy!h!=)5E>>QX78He-7N~Vt}&v zBF8UJY~@c^pB}86-E`YN`iS0O+t%>IHU&+YUzjnrR-VOI!=!3@ZAxe)qE%!_Wo@b| zV}Xvd9CCq|rZ%i!|Mu!P(J*}3X1owC8olMkD_2X5^FZP^fs*SVVOo(w} zhDucRId{e%B%Iv?S-|q!dsBVg92@rQjVX*N3x6+0*b@A$qR zXdvo-VBw&^yYOC@cTvjXqxSQ!A8Use@Rn73JpPNn``n#wmG{6Ym3DWLGPgF?I(zqA ztXXNZnn`oI-j;)lm3wu#|GcTdMb&W?RipKfl-y5;e~e1Wlzif1`a7?Op~0_Mev7Hg zA&pcW6Vjmp(!~?1%>0pmvYL3Qw2Ly*A$67s0k_T?E0p&f`W{-C7V-7JzT8(EX+^J& z8X4PhF%4l;#Z7`mbIVajPn1_Wn|MBynS=#HJ2}b>urd=dEMOf++$(e z(5EXbe-`G;sV^3bM@iqyFT_7iSC1QtDzB3d4S9e5L@&>Yk>Y@Jbc$m{Qs7A{SPv<|Fe(oNjEY+e_oj{ghf56q4w8@CvTqpOBsiJN@yXV6?AlL zhmo2wNjvyS#GA~c#}X3CxA~fPjr6Y1ZeyhNIab3437+^lFP(hOePl%F)oWh))cV5m z<`SOS3%jz_PC2c=m@Q5JfR&Nr!QX2S<_nAc;?`^qV>~%gdAG*N<_RrrTCk7w-|Gaj zw9#{H^Dz$y3DN5RSn;CGly6^GuThxA#=n#5s2ZK=9#g)MU&bkMU(53@B;VJyxY#fE z_tM@G5?0yl->+$f4f9)DrPiArvg7!B*)#knc4_!ZnfulJcd4+h=X_i~00s2X=!PeG zt?O27fu#88DeW8`wQcx_Z=T`&yu(94!?;g^;Tg(lZ&LuQ;3xiEGAp!V!FTqFFR}e; zXlMjHed-M-cMRIZg|O2S-@bBOlsx)@W?1&4KUwh;%ATGvY=viI`h=mx`W(II>gxJ# z|M9h3-@bi=LtyikEpJBDi3cjH5F?MSFgk5vE#1FfN_sdrA&)Y9U=<2S?eJ_{d|AA! zD+%;MTb^U)J4H0n`G=o22eiXN4Mv6 z6nL*bMz%k1am98odV4}_+#NDIGgJKL{QC;&-8|OBckuI5h=*+n3=A}Js;;i4MzG_3 za)yr{ac(!7Ze04pSE&@OPJg88#ddloVO?*CiGF-wATb#0v{Q7&7H=7=MM#My=$^$4gyZm+!93 zHkvq@O!b!cG5W{e8Et9k8b?tjkAwtcbaZqGV^FNr-G#SJZd*AKQxS_a?No^yKKh!^ z|JA#$G#4b*RC&j>g3|jX80PqL6IGKM3>K&Qt~S5pMa{yuk9V%aB7W?t^U|Do?o@?f zJW8&I&|Frs^DZ5F=8;^Hep6nuP*7BiR_9aY7?c|269%bm7D1 z`q!uSCH+BtFCWmevp*^;D>Kl4-Qlm#dc=0@D4a#zzkc~ZWHcD44kxQ;pxpFnv7hZB zrz{7)ax*1m(R`RB9!EJde`Nu)cUYiej_hZ{@LKEUYqD&@N$ZLgJg&qE4{ygNnlGA3pn>0-tW z)C07-wJlwdS(!NtdxUQ~6C>k&`|18@Wb`_D4hL8zZg^uEcYjYfOL7g|dAtYZb7@T}ZInlWl_;O<6X7n;#3EZKT-;%UNVx~MJ2H;vugM@+ zz&{->YcTmZGNO}-Ny9N>7H9^_tSwushKa{EHG)E}jBN+E%Z{@B-Dp7bKr87Sx2Whg z;{Sq?zpQTYt1dP`IhJ@RXw+W6>f@*u&&c!k?RlM{T?;)J`QY1Y4FVsoH&UaJet*_z zflgjYiII;E7Ke{%ggu%5-N{X3o%#MC{CkRh=r&VPDME*zz)1fr3*2e4m+5+yd7@_K zGLYb7t0YGxN9cD<1$09}nwXycjK@O?P4U5^ofWK2QGweAF{83=Bsni?cCOG$x3+aF zQy&{||EeqLO_9)dnq>e~oBYCN8LVSb@_=D8HT9RwPG>3-SbiE|-7Hs>7zX{ctbe_A zZmiuGZkP2Soj!ldbF@8p4I3c><##9%b20@_btTeI4BbFYyf!&LNf1_1TLB_}5#jK4o+?j8_l; zJ6`HocxguEwC-~t>GnS4zWk=6$KbJYtg&CZN~my=XF2-p0C44(5ciCd_uE6?DTvN4 zXr5OKj1?5>ixsOSo}HPNR+wu)?U6tI_;fF|4XRgleKQ7zh8|!${TeCD38Ni7?ZBHi zLZpJMTR*p9Y7P!w{b1h8h&me{^v=38GzZ7k1itA?-K&!d_b$DF6yAke?E`kH#+6UV z%Jb3|$hR=Nvg|WKO1utC0m@Ir7M%AUa6#bG$+!_FdZO!{ab@Dj%AW{#)V{-UT)Mj{ zn-2?2DAYy-BOR^iMad){tHF<1qkWZY3_gD5Wpw4dj-JE`Z7qUjI!m$1jkIY$QuXy0 zTspK|@VumLR>}7=4?HhowSF$pyqA*%N%~Q7@lleTkPRmy@*i)`yF(&7w;1vVC~hXLU%$Q((8#?tfV5h&gxQkTVG$aYgtdw{vj#VTfkN+SxKPGE8bB6O>sM zT?q^jpV*9{kCsnUR8WBRO(SI#y(j4LD)9e1*U@9OTczZh*^l5>&GO!kZ{N1VGNzP%t--ZTu+lhhV717T zY5^PQ)($EP3O888a&vPhN;zFFciG+$rdMdbm_^`iwJhzyG1n1WkL&LMZ1IUcK`}<8ktU4{tUBPxomfG8E zL@K}oz}Vwv+hI>$`DE{Bv}^O6L+<_7Y00Lkwe@GXZAT$F=Uvx<2*;FK?^(ffZ{*;r zQF_Gc=|#iI$b$E`9#yH{q594&n4c2A99g97L=n9v8}(hTV8aCT^E|yJnBFBq#_6}* zE?W6$b>=O*uM92!#Xi~xu6^HJSXfAw`XI}oHRd=C<}?`=iXHa3TdT|V_`k1fONt~r z>^8veieW0oyV}mkc&_)d!y-e-pV?se<)PbAp2DUy!&`7o3F&6lMme1w-YabS&ghNW zzB3mbtimiVAQ|$y|A|+>PZ~Q?v^+B5T)mOyxC$5mf#V30p7DeN`}Rlx_+HE zmf6nwA1^?h>ZoRz#UiShn{w^<0a5A=I*0aX{solA29`(d(8g$GRvV5rR;QVNi2i(} zKv3IG+x^Z8n6bO-Hvi2ow+DJ^=~$(nOY+ULjHvL(^JDl0 zj%;}!-!N1`?e=H7ZCIr`bOPYr*h|j%4=~;uAEzlGn8^RmN>`isL>aA}?#Ym3p2k8- zm9c51*L%e8o9-c$v@%+NY2&1_w$}=e9TPMu!_WCH&5vszwKgg-Ff@#A{KXY=E}@(2 z&owH5sw>WY1MdD{U};I?c=2NVhYM}l*5ty%!l2AEe=q5miGyqdKt|Tg6{38_@;X)W zY3=4K#CQfW7*Z>QM2iEIpB!s%YYTYtj56>vd7#e2tgM4Z=IxoLf(8n0au2`bdvjU1r-+2HK9le@P0lmN;mk6it8 z*AI|{C~HyRuD8Y`GH%T~u`%!HdbaEx20pJ|K6@>2`bEy^!D0hBAth)}0!MZci2gUt zWoiY6Wa3`g)4yWFIC=8q2~|}OjRd1m=Ji%NDOfO{+uOsnNB)fAON`;M#IJ3yi@bJe z^U$)vWkT!*jiK^jZ8+_qh|eL&mtq;amM*SqS_mY0>7Ymr73ZKFR}OfD?Tc(fU7` zi}5`jcVIf7S@oaBEqtAba~0Gfg9*EoRn&fj#@@@ya=bd&`rV2c)j%y3tZDQn zbj8L-;1fh(Pk8^p0z=?%ZOybKP~A-{t0MfXyRT2HnVU{pE2UIdbZMde`)EshJG*7> zB$=+RZpB{bmuoNoF6lVcJDP*ProMhvU7o5G(Rq7$9a67H=wM0dvbJJ-?7sRhVly^x z`JilOi`1#)G{`vs$$beUE}pB^$M}|fR-Lv6a9h8S-QV5$BvGbnHKgoro`m>u#|?+g zvrANtYKD}QlyqY&!nqZDh-*V)D+JI7=!ToXBQlZ`hJU~L4o4a!5ok9|frq*Lp(EjJ z+>-@?nniooIiJNo+1+-}V9dDE^1%%A4F6==j9y4Hh6Ag6eB4swJW1!h$yUItN6!vi z=i%eqjE;6JngSv6VUTlB_MSE|JL~E1Pji0@%RS&N=HNvH&F-H+-3tojUP#$%*tsC{ zxmx#%0;@|!dW~1iH0K;2J&`p)Cq9)T3;q%@x&%T?CGTqDkXieWH-R$TjLp7Yii_9o z@OgdYT8inY?ab3`zQUk!rQ8V?SfZC4DoB0;+LZuf)WR!1(vnVvsFD&ds@!MRl-AnX zYFH7>AHuE_`*w+2cp!a<%xI^K`?bo_+L5K|TxAUo`E&y*Bf}>JHs5Z^3Gt`i^zlx7 z1LxtJOF4{gZf?vncMraJ@#4YWVdy%557B1zuNPLA#=#F?GH8eGrr_QtDpBWUJIp)8 z%Fu*}`%Vt$wHgfXP3hVo6_iI&*;|YD!$B1yNd5ddWhD|uY&)I2&_RhuSeTlarUnK) zsI?LWvWzCorVjICkB}FAE-$B$k&#(I&+J;{J_z_sBrrdocx6S6jZDy{(S3@HM2Lga z12xCd2x_q zgx!BLe^}0O#?*TxoI9nN)MD)zcqm7D#@`}TJ01;4%2(D_=LvTCA^Q==t>|1nJJdiV z&$)9g*MTjMD=8@*^HeAaI1y3pq1k(3-$0)p`QwZY+-w=7Yx`0=hRR(#Ud?Ccalgy8QS#_=R`~LmFNuWzK!K0UbY7XNhDW)nctg{Lo1}}SO!rC5`Eb3~&dkFH(qL<~O-B6t2w4Ijr9=3ujUQRQEXRwVC?+|&% z;I|m^^&2+0wY}e~@oP|vP?k9Wgk?d0P-5kKxL@~HrbiockiiOCD)6heBr%Spxue%$a>XtnPKq{>#TUiVR5uUJODRyNmoBBH;5 zHQwd?mX)7Jwlz$+oyt!LuyNUE+VY7(J(-!Dq<-I<+pL-GT_9E9p`VA!z6iTt`|KF7 zf0%6XJLjVxn@At0y#n%<_YTsHEAFUeoZ@HW()dpM`uff_*J~vk2kFM-N7i=q1~n>b zw&&>P)A8^aPLZ_?VLX6gDNoh3jx+XlbrDq_KY{@N-Vnq(8DAP>KsVU2B1866${mZ&B8LdJ;|$Gh;SJwoR>MIpwYo=kc;#bhH= zk* zXC0}I!*YYfq1L!lsT8#wD=g3U<#5*zuM6D#dk;;to-EZf>m|2`d$u*iQ$6Rfly6Dx zaZu4L`;(+z`OH@_T_YR&B%T5_A?ah%@&qD(Ow&f!9UhVuO4cDudfg>2QeLywdSY!nK zg)F`akt@&`($vI6w<4-1NZGP}Jb`6hIVc%p1!5OkCiaRg?1$-5Lv#2^m{+jp$E%1Fxn{p*fmn4T-oFtljZdB&{D@eYWBk(SVmh|#5W=-@&Muj z5iZbXa(U<$aoh>GgZn3gc5@#&!iMx}BWb@`-A3ec1QAqm{MfO=*4B#$ZN!ablg}lg zat+Gem#)}QJq5H^KubkmjQSOfGoeVJd4OKxctevEee7kaFHaQD`<22bn<-ZOfpN3bvoI1q(y;A0gJqj1giy!gv>8m7yC1b zgkAK6vhuy~aCSsA=J(YH}$=<4b{>kV^d3Q3qkc zkFd1Bky?Ft1$_EnutR%r;>azp2x-Tnl9Ek89i^D)lRds73cG`%k>cxox|^*Y zrxYWPxVUZGHWKM-Lm~q>fLnvL+}(MP0SyRVG5ZoJ(2;Q(0gL&N)vIkmV85~A(y$;t zV6>lxax327Y??q%xe2?+HVzKG8;%Ic8%bb$*OO4^;t#_Q)zs={gT5v+B?0@roG zm_F*JR#xwB_P2b$6V3Nr!dwA0Riw)(c`|9Qe3kFAHPJj$vE`RmFWLIpet)jWG?vFE z?IhA;);ruTrdu^-zj}O_KPqQJ9;i}nD_~W%$V8Fmsz=`3TDg{&XrXZF_lyyy`pG42 zE~{jU=B#lNvrMgmgaG}^HcqDIq)4vo-CRKf{@(GqNXr$37-Im&Jztj;7k7alwwvmu z(6jFgQK%noNFoPsgq=AWR-M>uoxv+gXO?b1%^u&|)Q?V;Vz&p?xyA1OiVclY=L-lA z-^#|u7UX{&)s+`}SI^@GVL^C5ctA`02COf^Fo_znbyuLIc_Rq%eJk@(Ldi-#=({rw;(43T(SUNJqRvgnIrrLSq@h^Bn6+30 zI0TP_Wad$!f4p8Q)8oNhd$Xpu(S@c?PEIOsE((MYaz>WZk_2I3h1Uagh(VR{Z?9PHIHW$xx;PJ&a?duZHvUa#!9CQ=eESn+RU_dgrcC7>Bv1U zw)SU-Xc6H~COMZqYgzx;Mntj2gjDRtzGe8$%J@nCK$TNmNq3dL@bZXz!APx_Dk7de z*p|HyyZ(c`&>vsEkd?J(2A?}W$JRgQNR<)h(kV>qE4NoS=z;^>ed^g|=wDZ1D};Pf3c}jcMT!0I*yp& zA7ILF&W~N%!XecZrTr=)Hkaz69I(%V04$Q|9T*_c41mSw&dz+@ zA5J=52h*h*rO#UJP)XN+)_LmsYP;Y8uWND_cxKMCY>T)U60tnKe5Ch9a8QOL_DET- zrT44bmeTKM$y=YeFvlo7q~!s=h@GANO!9>TAe)XK-0-9m)L=J|N>B5b+@-zBF-OM;4wDbwvxKLu+OnsW_~9LBuJ2%P`L^bd}~peJcIeJ+h6$f9bWra zM>9fyAi1KiFvCa5c_IM^%_@p!3Ouro&{aJ=JP2t8DzCu)FK2M%#;xBoX1du{n~?F6 ztT<`NNr1ebw8796yF;|~NR%-CNY?h9n5b0ebi-KEZa7ogBj#T^Gh z>SDy<-n90Z2Q!4!7Q?GAJp75*|E%D(cEQv38Txg%WZo>;rtUA+Tdh6D=`}WX%zMSk zqV!vzG+F9}tp#GHZ^)W+Iu+~QF?}$dSFoMtylNxj)}NWmHF}u!o$U`DsT3Z=WN)RT zJlmns`M{#bsBB@`k?R9@Es=|Xki2>GCZyi`?qQem92!PAgO{hq3@hl^+4r_R50<=o zauuLdx&`CE35BJ|YUHt9dNNtL1Wbiy-!7k6^x|#LM@vU^mBfZ7OhpSLC_E=u?eQ z0lMEgOxzZA+ut?jyWX90xJvy-B8i>nWkuJoUli!6-`$&d2;wFU6H};$ZTWGQIkwp5 z`TkpX?s(?q<%wQ9WJTwWRxzkSuQDh-fHDwd?g&Xm$T&Px68QR@S+nO~ekmy_1Y-d> zQBoVN=&MRuIo$Lnst&WL+R?19-NXS59%|ibaJmv55hXVdyJ;lsXO<=8el)kEg&EaT zzL|3O1N#lr$@=+vS#{x|H|B;KD!HzJA}xT*DQa51qbK=cnU`djH zZ@DR|DnUPQ&wz}B*>J!MDoYlAbxS=`d!AsxDIJPd-oSwT{5=EKF6R8vHkFBQk9WhW zzyMeZVxkBN7!Ia%t&dYPgep4N{C>}l9Xmk8e2Z0K!du@EDxy!M?2vFg0b4>7e7^yO z5j`HFKLH(Wp3VOFk-%g`*G437Hz#|JMOU8UfP)xB6AZ)@5Z5r?IF%B9_vZxW#fGk% z=fH6N$D8dRpL>@W+#YLVA#yb6w1C?l;7@w6$CZ5f)!Vx0t=ftN>42>I~h0O%?h8NDi$KX(4dCJ_;l zyAy@v3tjFssvoT)Bden3Nnz~YTV-pu9$nwum94&)ZR=>-XsztW4VS*J1>KOGiAsywK^N0n>n~$0_MqikvCdttnWp^qY3XF_7V|q}~?e2onq?BkDi9`k_n%E%4Ka;=Y4;tuwY-BFf;Fa&l_K9jl8Ju&y=JQe1ci$N!PY@iKjRfI9)dI z%(n#C?4W)gI`C9In%nS>kJCj3i6N@^C;3~QDh$2Z(mn59D6fo!AWb+s2+C34d2tgc zgm;A>dLjz*?hKzpKn{vz(W5;($98PAUgiCGRXw5|Rw;}~n?S7*<}NhL;CoT__WP$d z@FoKad8Ve~a0ML>>-l<;dfaJt#9t;z&WcJ(WPsTZ*fkS*=1O1hI1)T(CnO{DNg+oW zeT&&JrHZU7TsBQ(zK|IY)I`$s?%n}I(-)LsdSj|W3yVU~h6dqQ*ia1{3>n(d(r4@; zdKE18g+4uED-0qT>Zr-&VtH$d?P!Z9+WxVr4!7sn21cUs2OE*Q-pw`EYh1dwXQkKb z5cnpr%M{3jQE~O;@aes$S~oRzzk9*;{^%0EP^4kbJUQR7#ED$VW#a@KZDd{623RV954evg+GY4btptpgs|?* zenN8Z-mMtG&rle|?5B*n11}%dTqUHN;e{1w{5qKy;on9NOG{%r8G&JaU~;b2GBlgq z%((lOfY$xLN=~WAOo_WH*yMK{vf7A370A_TEyWyCr+Edx2+nKrLl?!4N7O^{fK0~vBJjGy z+z7waVNY-GH`<6aST6o$WhdO%`2pIn?!W4ajWGspC`K1y$?YML2p>cc21D#gCLC1R zXV)KQT8qe|;6L_WLh5vE#bqDC`L$nv${__p!9byJ3C915sVO-P4L$`!+wfzT9HlX? z+n@`{+M9gJq(+_)dZgAf)!m8&5InMl=N*?t<54ZTr6NLW!_WCc{{waMfAG-+UV&^5 z>q6Rwe;(X3{5rd`Eg|y#*WXCr5xQ0QqWwQbq5qSb&;K(=@&8*T>3@6GOH9c(|KkOy zI4O99WC$TrTwEjitLkwZ8^-U~7(QIs`ihqSm4tX%pUvA$YxEW0ca#U^rYabD{AhM3 z-nNPii9Ndf*-<@7%k#C_2iB_}SdEPN10O%$%*Mtdb=^TxI5R0&hmf1`BcKv;YK(JF zad&ypMv^ORG`Qf6KAV8n7DeHpofktMjR^6g&qH9es^^8|qIO5In|BhZZEa~txexw{ z&uU%*p@f|Xbs2K!Y<80h%F8z$NNl{PBP7OWDwye>+(zAyxbAQ`qd$kN+=UjpU9$EM zzrNY>eJ-)a;`iUXp3#iA+Avg7(s>LQ*hR~qd#yq7l>cE*+NFEN1{BvEzPoAf<%FLO z1+9~|fq+<>_q@EA^O2dEw)ad=S(4-&lmzPPB7#+3XqABa zf;nZbg4+GxQ=ey09-BR(>advQiE@STZ=1W6OP5 z@nd7>ul|PqCyG29y>M8QlN|1-8S&Le{fG~UR&{sJ3o5^bld0E1yUns4=U81`vLuLK zLgSeqYp;rko3fc3IS;ZLEYG>W7Hqs{pTw^rOAlvWj4f1GryQg9u>Ie4v(OW}7*jf6 zzkSL;D22|yf9-)Ei5|gvJqfx{)0@Kr573aF?qAt+;^A_qa~ZTGt{{dnKN`|MT>(~B zGYu#4upOj;@FPRcW&~GDB7mv;yvss2IpJW0ibdGH9#;)TS!d{ zgE9Uj62KMRP}%TyoG5MwA37>up8R&)`DX^ae4u6g*b#JLuSx|K9KB2kO{Y>s#&^l< z<;4bu(pUDaefa=cLpA&`1N>Pf?`vdyA;b|?)Sir z8?ES^dpja7e?<^YyWS`aoroO+|Ve zSRteliS%7Qum2;^E2FUPW)e8jpovc?$HsA>?%=hf!LUJ;B1d04cThM~#>BfN6~LE^ zy4)QEy1=1u`{G@?i#$==yU-h?Mu^q0#?K5l(jY3q=&=zTEDdb%ZAi0$?XRMr=<4rb z5z;o=wR;a6!b0Cd=v7E+=)pCMOyLFh0i8*-aU@Dv(F9C+*_kNJRFhfUNJ2mmgKzCh z3sh>@GRb=9gwg8vk*GNiK-R&@IHZEoQgVc8$&W&R*Im4kR)0m_(Z|z5jv)fAJhKU! z0wh;#6vNhNGQ9)qjao|~Ldxqx8!RL4OIU-)pnvK7<5P0Su(zP2utJLx#GJM9ARCVdB&{x#l0Nz~&1s!3|z>U_pA8oV3H&p`D^= z0DDIlI;0V51>tl68`XmY>582-kEVOPw}vB3YLqlE|$rBI{t711g`xp zXL(tdB(6QiOUs6qhwvRSE;375_qAUa33(>z`{~oCt2h`HS>QHiW^bHMDi^K3xqbkz z5&SnH=_BnTvIbGh4k`D;A1;`WNu7N7g#dmKJBquc0d=`Dm++xsf_+D`L=vxVx@3Aa zloKvkCxBVx?%tJBddTbs?V<<%MEZ{v19v(_PGXBfsWYXN-Gm(T1}-%urxVSlk%eFe z_g>7{|MW+urT)Q#2Mb_Diiq%xd;qzQ`00nmKQB2MDDzF*tK5;D1*Uzw=QFGv-^*m) z`l+}|@D@#Ah@!;_?F?^%P^zJ|Gor5gX0$kbErmpu4m_k9DZ@?z zNwf|dAEl4IUgI)ePB+*uIg0t#=NC+&BNIv-&TFD3)utI9Cr(EJHH2n;?h_IGSkAue zjbaRp4fShR_>R=mX~!K%^u8TsGODC z-mbNMd%&gQW10o&+~6Z= zxU!^JMbdm*+^bijpyA=REP=*H75u9`M-n?-cXDP2&+gs#k?}C_!6MHLu^X+d&l0{G zrIz!=bPP_5sK5w`j{M<6rdqv4~UruIy)pWvuY?XN0cJtwnAK zQ^ea~o@M$IZ33r~+uE$h`}*9IlGseFg-vTpI@K?k)_gIP7yu`HKQ3=PB4}AO-14UkwucL!1(pD8;s_4kGqQA@F?9^eAM+knQnJE31HzO8AAwrQ@f&9c zvrSl?Z^g{{{rELJtb$F3+tO*Bwzf7r#qmhkdR12cnDLLk>JdfZ(|L?>9B+z?ps=UQ&w9n+er~ z(ED5gfi)n4w{isi-8_QTy!=Oa4;~!3Kg1_lKebLuDtBUtm@oYzdrc_Ib5#t z78Yn$QhLa7Yzw2xWDu1Q<30={9jD8V_lKBlZPnHd6Sx7iece{M+)CS2GWs`}>`N@6HJaISR_=lLWM;_V6C?`5wGW*wloc552fOaR!Zy zOvr%?B7bp{i*n!LY;sZNEt*pY&XhN9Eb#Qr-_T`ADfF}K&+0mQw8G0OGwNR>6z|}N zj~)Mg3FYZ>G_xRnPHfU18_&*f?{^6;oWFQw{EW7+Zr!iHA4~A&XwK=%NS|#^Sj|jM ze#z%pWi8I_6}lQ;<<}`yd6@p+)o9OHMVj^o@0jD5<{K9M_tna(^KBdSQ@&mv7n^@a z{m+;9N;9}^gP`FSWA=OhzCM9Jo7_Mx`^lZnf1imb_H{4E3FSKi!`uFIp;Q0sUgLW8 z{{HQ&duOfwje?0p9Q8m8>6%p6fn-$A%E~@AG(l* z>N!vZm3x#Mfl>Zp;R2NldF^X}Cx{fNJBd@E6F**Az6N8#4sg&vqrEuZwK}6IF90vm zLV{A-0?ZXKBXkOTPt=Uu1oqMh$!3^^g(V0?nJ5hSU@EV*I(HXsT3xJhc^n*U)cWJ~ zDK^L|NYm!-7z(Q4pc;4|EVP$EX={X~|Cw|QL64WLaJ2Jz0OtE19vcC6D!@C0fg}Wv z{UBKtRUmMt@u7GIeFMF)(@da420D_Mf;QHQss@1&248&uI@i*-n4CUM4G%*Pp{Z3? z`htfe96aCv%5fJex~E4*o6_6~JOhEU)dtzYYqdx}^cIaS-GP3j&|$vehV`5mjj#Q9 zQw}W$?M(Kb3A=d464wQ<@EY8?6i$*Ax|s3RW~44w1t-gUCFo|qGk*?+6^9K0eRdX{ zf5Tky`<|S=@1KQgA9m7U3|&kE1IwUJgE$ z?bM9EeHj_HJBcubz%`OF+WejgSO#yQG6<&_QbCBBLx+3-V_X80;$jp=kAHS~4XHNurer+X+hTh%&r9l+plo%9V z7Ht|r-(zlozL$8Rxj5c(Q_BaxTx!<+W#>9k^2xIQDv@&V3Wr9P8?C=wcyCiKkok+l zcOC$OqgSgYtSdMA;H@Gm9h&nTB@wz&D&`4e02ImV+BG;0G)&4~oH%?EA*v6-j__{2 z(a(>-lmf^1C4gJeZm!vMvo zAtmJH=l8*ZidIR%goIqOwood2)5fMB z^;u+>QGzLjV_=ydDRJDLkjFk*g1HELQ#TG1eeXLB58OaX&KQvwp~IgjU@TtEz|D(| z$|@?K(M&~HLkCR;8SGPF6hbf7jHNB*OYB)UyYGEAw$RFh_lOvH!ipaAt;}`Z1_F?w zk9C@paO2eMEH5u_Y}x!4I7h1>JzP~8%)HTDggveRw}7*ah-3hV;Rb$kTB2oUh8lEy z0fu@OFbkud3Yd`?RpKtuZ}b^9927H8r)?wYb->8BbI{Fub&U0|i$w z-ddHi+Y>i@Le58BN*%cuW32?D>#W|13G}{_apXQ zfei!)wcW#L24Lh`9_{yMlk|g^n{XjV+?_g^!!X8fHhckNOv=j1IkJpnvrN`^_4OHN zwl_31WYh$TXTIw|x;g=+km&D>(2J8ByxTu+Ys6^~0^-6`CJfjQ-H;A~Z(%2KxGdjN z-A#w55+Y_H8uXw)!teUoW?M_CM5~NXK)#D zIzz(R$_f(u`@Lq59zMixd18ZE@AIa_;0mTWidV~iJSjJNiBkHzOQV?|u6|n&`$X%p z9h{t;UjF-@SD})w9tm=*(8i$hVo0ev>DRQP2L#a$9%1y^ezSY9EF(eqJ!m`d#XJT3(>jO48G#ItOx-uX2zOfh>SI`{cH&al%_nPIR_RRE zZ|xR$`um&n^<#Gsr7>$2-4;;O1-Q`%)iphb*(got!KJmrz@Kl%(e#dGD$@6QnCkAK z#?+c4>ysYW6VD7MY{#;(1hAr0@ zrHQ2$F2omtEW;T?QK;hx$ozd+PEO9XUAfN>HK>R2*InO^bEcaQ!;-;ycVZo$d+)96 zA{{#Kwzf8&N)J!ZGx^R=Ip%0WV3V2}UM*wzWebOW?{;USlx#{luj33MpxX1?%od2J@~-}VH(Ockl$W}r4iEs>mx1V3f{K; zY=gFaw9l<3`lx9S{h5?$OQQ!|{MA^pBt_l6V1O#`|kO;nzWH{894#&D!kT z+-?*D5pvQ7V)~&4Kn(_+DB%Q5+Z!-45c>FW5%An8Y%4@{EG!48uiQ43tR>fR?_O_v zqiV;s2@-;4TFFgmzl=M3u>zs9vpcNjhJ3sF3a;&CY|=KZU~J8wYmA-=)Dw*j5%VUdrh15- zx|AJZqsbw)^rN$90~RQit~!sUgex#xsPLti${_+7oKvsgF_mB<8mBmEUcPbTM&PUo zdU*u|5Egyd+zEJ5BIEaN*W?k0f6>0KY-O){U2#NiLMP6%36MN+c~QAEOJD2#wXdJey0X-gMjdwqAga6M6Lj;eA0<{KHjtc#qH16Q+)a8luM zDCr@fh}IJvX6xo2l>ZPFBcPS8K;lHOMm4q%b|YD|YzVyb`}glDDC+OAK_I9pVLu=y zzV1G!H8}F4U|>*vF7YVR`L_=!Q~3@a7tiDo=bh#Zpq|ILktIp=b#BMoGsdh2+R}jA zc6B~~jqq@_CJy*LA#eva;S4GT$s|4BlA@jx-(PS?fa1i)Zz#&#lw&J`-72H_8>%P_ zJ!N=mDz5IYgO?f^9Z?8jBtD60H-+*RREWFbCF8pgm%B$sRMpkD;gy*n&J!4fIRLP+OiU~e=7gxtS5eJ+4#h=qsu>O;iBhl~z>0C8P>dn;DCPYl1 z{<^Q^$E9Z(lyodCf=-mFHXWQeUEzP?nbPI()0N?ExF3p}Hw=RqADE*M&DQN(#S zC^8}nh*}SmfJMJt-T&@Jvv_OF#FWT3ZB_!IgGodHK7$B~&g54w){b8Q3@L7C2myqT zKmzu2VBk2)8*W@b7?A0D2|2}iJT*4O{#2KhB*oHnv-&S%d0MG@;rYvbBF8$$kiaNm zsS@LbFbkajdF(}~gx}+cKLxS;E?W}JPV(kAABgFt6U|5N8i^DZddljxoMFvgb5H9?ZAJT_chtvRfmT6G8RHGf z{9~-jBJVSPU&3eJr~IR$dTSKxr~WZb6}44QpQHxySG&%=Q${#A+Gtz?trpO~W^z7^x4Mf2q>HeenT2plQ%;QM7U8~N|Mn(iT z&Gq&62LwIGVQ^%4n`pHZ(iL^&ru8&mkj{U`Lpl4@SWUPZLG6-YZon0L#`@i!=j^da zu`s$+&Lg%;o1fV>ayb1zUVs_ygM-vPJ^n#YA{4G&6PJ;3&g5(Pf2eyCXsr8oU;J*KloF{V zPXjWCq6j_pD2WuALPV%cA!ODlbLM19ipmr+&mm(pna4sZ^E|u%pD#VnyZ1i(zt1^q zoqg6it<`$p-q_wPGg*Jrwt7|}JsC-@WmY0x{8d_clDP+MJrHwab5o&yKyaae^LSja3|m$mq`m~T zfg3Rh<$rU#ZPr0d3*Cv9w-nXHeYkFdiXJ|Em=A(a3dQtIjG6+R$MHrT_!nL#*a$zy zi#H=GzcDN9I2QuKMx9c{C;awToO771Qn_1xtPI3 zM4Zl~|HDCK;O!#jglqQreVPcg#&#f00QR)j{$8u|rRB0_;bE2*BDo1BUB?D0pz0K& zzz%>D}FzbY-xx7c^*DNh|MoOXn(|{Py`1um3(zG(!T8^L7{MMRQP=Bp1abvV@iUgr(iy~Mlmfe0YdC-&127tT;vpePj)iA9T%v63GXq5hMO|ZE zUbVyI;8(=1GGSWiYA0Y*j7}(*yP$HAe@XO;~OKMI>L$9ZeD zDe7#u1pWad)H3TdI=^RC#Ds@-3fKRJdjfZKbu>g>@Tv z4|%lNc;{a*xvJu;Eu2R6x{9zTjGuDFFEMSipD>*o))k-W6(qNoS`ca3A$bhP!@;?& z7x+ZY2o)D<05iP^xyIx_p|75{lp=-x#?j!N*ls;P#m zx3+CZzl#)a5>y3~xltMtQtyFdZ3tb+2jAo^@yaauLT-cI*iJ)6{kon26hM5N*<>h0 zOMWi^MQ376+B5Ko*03j1u=7)lvhwmII!e5{k-_o|I4=q6aS_ihjyqMFDkw`lZzeTZh>dcua)T1lL z>t38&25=C+CUN5DGN?r!5KTy{;jP&;ieX!BC^-A$t=#v~XEcq+UCeomUtM3@s$tcl zXehdPcrmDEY|FralBJ;VW3?+_LHv}gF9(p3G$UXSdEYdn%cbDhm!>a4b?k-C9~>ab zWFVktqd`K$I6}A{13V1H5xpgR%mmE_Iy;Zy(^pjubhFEy18V!DHjW7j&}d>-;=Q4tQ`g#%aoL3b z$dM4BTL`a^#9<2|?voasVZ6_3Tm{ESW0Ph19LpqCb-7aQvl^R%r|DbaXe8#U7BXtA zG}u7`@i$0{JB%$oiCZ0YiJow{PUuI3*+V3|Mm|;=Mnd(}}6f?rd#&pZu38 zIdk#!7&9D!p;Hi!?tH+Y)*S)`hJ6Y-HWpZ-m3Zb?a6(1Iydz^gQNRk|>B9oLJ|Exc z;^vmj`n~q$6r%BVLA~jk(boD=1pg=lq>lS^0|m&!Zhn4mh<<(W_fu-04Z4h>;bCY! zbBoG|-UM%X*S>wF5yKF4MiAM5e}x2tgalSRj*8RtfeR;^l%%4ukF809G!S8LpU3Wb zj%RNbX&BFe9_LcyIqY-dk!RLGrrw{fb#*4GVl|Ku_|Do_O66o3AG6ij4<8N!8}{O85blpKTnf0h3m~sBa?9i(iNi@&m?sQczk*p&&4^l}RhdVF{+m`F;Mrgj#J>yCeawAE`cED69_=GJZsji+aoL- z2!jYwv5{b|217j*5z@Vj^{H`^nSb-L<&&#Sr_4lf*th^ddM-Urim&l`L$~6}4D&VW z(iy9rva;Bh%zN_GT5{peU5m;SU1I}ctZ;*1?B?bbN;TBTD`1GMnoUw}Btv!#P@1SC>}#ZBZaF75VRE6zMj6IR#opg@v1GY55@ixNbi72Um|kAYZiR zTv=tlcE+@fg`6DAvD+~QiKzl+Ac@a}i+dECjn$QxmAT+NDI8Zhy0|hEC!B)=Omq)y zU$Z{L7ayj2`pqrLhXdW+5r?R`6|YGq>gX)zR9me|aTuUwY#i>t^$GLm%XQ66y1E&U z;v;zWjLrM8Pf=H;`%+yZMj0C_EQwA!(et~mmwSoEhqCg{E$Lh~&Z)(7lp?!J6%1K*rzFms-DfW^MW`%->G*Z1!a(L!9X zS+Cv}!6gss7s-Un!Z{maifbv)8wb zbo0E`+J83BK?4$>nF*Hme3Mm&nHfvksNz0wR^$9-zE-n=o#&wc)z7Uu^Rv~bfOQwr z>hl}VRzL>Z`pk+H?hM{1h|*-o_1Vc&0o+sfL3(dd)oZF{4v}!Y^;J&n>-C(9K>Kz1 z=|hoIqsc*b;@y}>$z+r^AY-=_GZ88ukL{#Rb{{$uc4$R@rPuuNJNL(~*8GZKva`Yu zm;bo%5t`;_QRg3qgs6wv_y62o@g-it&3Z&!2ORWQXPHPubi<4e1i#fZO?4R_Ky!p;419dCN@3wDUSn>YO3(V8#^qwp89nD`+ZH0QIc+}pm22X z?gF7D4#5`N{D@{YzcnXUfFnNcOKrJrFOU#Y$L6srA7ZJ%lI&7v7CU!mXHlIJ54~Sa zRJ}=s2?^;vLBwdC)hESJE_rKL2B$r|E9i2g zcXIXDuLn(R=BN(c$3gK|qi88{rSj?(J2IjtFTlIC)}LOrqFgimx_3jegnskn$G>Dxcp)|aD6KyA6ueb@os3iw+8{ArI*!8gpP9;1zKn=(f)FO z!>BX%fq^F^yaEH+cSRIn@r-;K>;|jTQ6*~7JZOv7-P`pv`J76P=(o~?2U-UJoPuyl z4?yjS*9+)8cN|`OwDA7e&$c{a+B730(f*#PbuTZ@ZD?|x#h1D>PtXnIh%Q4L_%3@` zdt1&PtU(Ui{{UBHKZx&mTimu}5D?!Rk%60|QHrd1lcm!W6N}og;Z@fo4-b9aV++DI zD?;SW-?BET760qdnxBua!qm;xq5p`$I9bn>;A>i1==5;@>p&3>#%ti9tZ zN6+=e()StRW!^Pa1U|{%|JIHf~9RI$&(NCv!Yk@q>N|-mYexud~O?Iy*DM~s{f>~4YY;EWZS`Oel69G)EUjDd7tr$;VcX3@H0(1Zq#eKO<#-Xg2CsMsY*>@oi?^x%tiWH7#y>t}x*K9*h)O@e zK}I2Z4G=@bxqx;k%6n^5qNxafRNyy-r)r;Q9&*gp|eqzruqv9$w11GOnO8$+QO(V?%;gkr2 zML}y%LXFS}9T~6JLG)qFhhfPSdwl3PC9ZsVv5A0|z_gsRx$=P$z5xk(RD&=o2;j~# zcE|b9<^3^>E`r70OD*)>W#)Rx<_DIK6nu6Z8lDCPS&dh=4bcQH;~EC@vs0D?fuewm zE>zM3F-VD3&+q|Cl?cv~g7z;uw|RYLDxbbkF!brfEdvcjlNT0=-&4(iwy|kP#9&0D zZ6ih@M@L6wO-MoeSC7Hecrbc!mA+QthNN?&ghbx%H2;Gh&23BnC9o@e`*sp(eE`f; zjcQ{gJl%UeAwI$IT)1YX;A80<$MbXt_^klt49u4l^6n|9ix9!{t*=kx)z;Y0#ap;l z@&P(l0c$1D2vERcjIUh4Fp>T53nUHd=s!V1JUVcd4$Y$F82k#MK%qvyD9G_!_Nr8c ziB%XRuy(d&<6z-QY%putV`0 zk@w`Inyd#Zcxn4}wW+SoPJrG=p=e**>*nbhh2U-s)nK$S{Fj=pbUH3J{M0r2bfeIv^gdzWZo z-Ts>ubZw}GAllu72M?eZ;8HP4DOv)H8HI-7HDKKofOHJ(*{RR4d2=Ba3sApQ*<0La zpb3C9p$mt0vvqeUM&*X18t@nK`~(uuTVkETZ5FDbbIhJeISH8`u`Jhz*QH0;Aiu2? za1HTHL&+aiIOFR3_;ES*{fc~Gz(!4rV$9cLU;A?=E>dtc*92yj*=GR109EDBsmM9{ z==X_h0%I`A%`jF2g-O88=5M*`rgPg2G~)o05EK^R&j=1ih8;gTG!nezeH<#|egtX^ zh!MPmoO(_W7rQ{i=L{^5pu+_JzU1lzun^qVjOUexB-`e9<~rREPcjqNQ$e0vle3~fG{VC+^MQG zo^LF8dKg4|SW;)ZZ(=ARxwZWK{Em6y#dD5_d{@Rs#PESBNF07Prf^{^&O*JM$~EJe z+V}nY2^`thI9T^@_n_Ij--&@siQpnlhw}mw5=^`Y3OJ$QLwMcCfDa}RZV*irUQx&Q z@9%J(l9dJ!o^}8JheT-#IfVeQEjaepTRW-~R2i@O6#tt2ztsO-wXPHO%y!#O)Vq+T zEMK+C9LeFh?36k)$}1~7VJ?is10lp09$X@1zxOvV+Z;Fb8x27T(LgUX7=G<|idWs& z%WJtULLuznt;zj{XB&=ny3^*zE?Bg+n!+SLt}=8qfc9Z=4Wm8*F^?fS>T6~n!g%lF_Z)9!B<>xPLo1zd@bg0| z3IPa-)Fq-O#PX6Zp;pZVMIDhT<6#yV3Xxz0fa=F&WZYXuBk?f<#_{fglM~snyUjJ%HZy_0f!;lomv85D9EZXy{>! zU-U#=3LPXzk_JdQykoa!6QSS+oVAde;3gBH96{DU&OgK)Lga#ZY>!d965Bro#~aBzUy@HU?NC;S!!q7scMFt;};LC~S2J~h%DheZ*D36zf-e|V>; zaD$r+0A110C=eurvc?(QX#j*7*u{o3k^LPV9fPJ|YcL7}C%!>erh!0EIxZ=c5}c!U zx|c5_LQWPmGm%Au5JQxPxBm+3ibC_fi710VM?Aj@en{=u zCH}%;g*v8*zF`BML#QQ*vgzf8&iCgj>6mEnM_b^FNF$93 zqVI?Du}PvATpOXsF4~XP?DpdF0D1TI*ROJH8kpH$$31II(3EImjEFR{wYBvP4SkQh zk0?bEqD?sB^z`%(_<}61Jk-@IcrSJa{s)Pr>P1K_$9WyH{?P*bd%5L(|1k$vNa%1* zfRRtFn^Io3vUf}Rk{60GTX1vk+o*|~0$M`5>7UV-q08Kg<$LFxJa_2Z57fnHJfy0t zBZ7v=99ylsnNgd|fKphS9r)?pzz>L`rUV6Tl%F=nvOKW;zA1i3i(K=d(D~r8WmN?= z{F<5h&;89`9(iIImYxI?CxTE;p&-ACHZ4N;Kas<}^S`CBu9K@+^<0YPO&RQ8FbC5=iEEvBB%qUm##wydo6uQ>!g$>|fqk(uR~v`N$KPq~e~1$r z`T>Yha3Ot$YZhUmZtjuKux0A=93{ZIM4|+GXw?t01uu3R{s%78CbSf+2M+j=as;&6 zFzzw9khWp>Uskj5&z9(~YqfkBK9N!qr7U`I-w%x3!ddsXBxT)scXdwvIuozlsxI)4m=^~@46YAR2wevZUdY~NHxEo>?o z)IIBFZQ<-n<@S^$Y=|@b3_}L&It)lniPet>q9B-@tR?>}X=PLdKPL zPfi#vvicnHn}b@nHmtNxUXq=YL%I&4l%0DhydriVb}dgbTIehtHyclW>xmdB(})5R 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 z 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 setQuery({ diff --git a/mypy-baseline.txt b/mypy-baseline.txt index 9d5fe48cb5777..b8d2d1c94da64 100644 --- a/mypy-baseline.txt +++ b/mypy-baseline.txt @@ -85,6 +85,7 @@ posthog/hogql/parser.py:0: error: "None" has no attribute "text" [attr-defined] posthog/hogql/parser.py:0: error: "None" has no attribute "text" [attr-defined] posthog/hogql/parser.py:0: error: Statement is unreachable [unreachable] posthog/hogql/database/schema/person_distinct_ids.py:0: error: Argument 1 to "select_from_person_distinct_ids_table" has incompatible type "dict[str, list[str]]"; expected "dict[str, list[str | int]]" [arg-type] +posthog/hogql/database/schema/person_distinct_id_overrides.py:0: error: Argument 1 to "select_from_person_distinct_id_overrides_table" has incompatible type "dict[str, list[str]]"; expected "dict[str, list[str | int]]" [arg-type] posthog/hogql/database/schema/cohort_people.py:0: error: Argument "chain" to "Field" has incompatible type "list[str]"; expected "list[str | int]" [arg-type] posthog/hogql/database/schema/cohort_people.py:0: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance posthog/hogql/database/schema/cohort_people.py:0: note: Consider using "Sequence" instead, which is covariant @@ -105,6 +106,7 @@ posthog/hogql/database/database.py:0: error: "FieldOrTable" has no attribute "fi posthog/hogql/database/database.py:0: error: "FieldOrTable" has no attribute "fields" [attr-defined] posthog/hogql/database/database.py:0: error: "FieldOrTable" has no attribute "fields" [attr-defined] posthog/hogql/database/database.py:0: error: "FieldOrTable" has no attribute "fields" [attr-defined] +posthog/hogql/database/database.py:0: error: "FieldOrTable" has no attribute "fields" [attr-defined] posthog/hogql/database/database.py:0: error: Incompatible types (expression has type "Literal['view', 'lazy_table']", TypedDict item "type" has type "Literal['integer', 'float', 'string', 'datetime', 'date', 'boolean', 'array', 'json', 'lazy_table', 'virtual_table', 'field_traverser', 'expression']") [typeddict-item] posthog/warehouse/models/datawarehouse_saved_query.py:0: error: Argument 1 to "create_hogql_database" has incompatible type "int | None"; expected "int" [arg-type] posthog/warehouse/models/datawarehouse_saved_query.py:0: error: Incompatible types in assignment (expression has type "Expr", variable has type "SelectQuery | SelectUnionQuery") [assignment] diff --git a/posthog/hogql/database/database.py b/posthog/hogql/database/database.py index 6909211070e59..de12a8267d911 100644 --- a/posthog/hogql/database/database.py +++ b/posthog/hogql/database/database.py @@ -31,6 +31,11 @@ from posthog.hogql.database.schema.events import EventsTable from posthog.hogql.database.schema.groups import GroupsTable, RawGroupsTable from posthog.hogql.database.schema.numbers import NumbersTable +from posthog.hogql.database.schema.person_distinct_id_overrides import ( + PersonDistinctIdOverridesTable, + RawPersonDistinctIdOverridesTable, + join_with_person_distinct_id_overrides_table, +) from posthog.hogql.database.schema.person_distinct_ids import ( PersonDistinctIdsTable, RawPersonDistinctIdsTable, @@ -66,6 +71,7 @@ class Database(BaseModel): groups: GroupsTable = GroupsTable() persons: PersonsTable = PersonsTable() person_distinct_ids: PersonDistinctIdsTable = PersonDistinctIdsTable() + person_distinct_id_overrides: PersonDistinctIdOverridesTable = PersonDistinctIdOverridesTable() person_overrides: PersonOverridesTable = PersonOverridesTable() session_replay_events: SessionReplayEventsTable = SessionReplayEventsTable() @@ -81,6 +87,7 @@ class Database(BaseModel): raw_persons: RawPersonsTable = RawPersonsTable() raw_groups: RawGroupsTable = RawGroupsTable() raw_cohort_people: RawCohortPeople = RawCohortPeople() + raw_person_distinct_id_overrides: RawPersonDistinctIdOverridesTable = RawPersonDistinctIdOverridesTable() raw_person_overrides: RawPersonOverridesTable = RawPersonOverridesTable() raw_sessions: RawSessionsTable = RawSessionsTable() @@ -186,6 +193,24 @@ def create_hogql_database( database.events.fields["poe"].fields["id"] = database.events.fields["person_id"] database.events.fields["person"] = FieldTraverser(chain=["poe"]) + elif modifiers.personsOnEventsMode == PersonsOnEventsMode.v3_enabled: + database.events.fields["event_person_id"] = StringDatabaseField(name="person_id") + database.events.fields["override"] = LazyJoin( + from_field=["distinct_id"], # ??? + join_table=PersonDistinctIdOverridesTable(), + join_function=join_with_person_distinct_id_overrides_table, + ) + database.events.fields["person_id"] = ExpressionField( + name="person_id", + expr=parse_expr( + # NOTE: assumes `join_use_nulls = 0` (the default), as ``override.distinct_id`` is not Nullable + "if(not(empty(override.distinct_id)), override.person_id, event_person_id)", + start=None, + ), + ) + database.events.fields["poe"].fields["id"] = database.events.fields["person_id"] + database.events.fields["person"] = FieldTraverser(chain=["poe"]) + database.persons.fields["$virt_initial_referring_domain_type"] = create_initial_domain_type( "$virt_initial_referring_domain_type" ) diff --git a/posthog/hogql/database/schema/person_distinct_id_overrides.py b/posthog/hogql/database/schema/person_distinct_id_overrides.py new file mode 100644 index 0000000000000..ae31440b10b7d --- /dev/null +++ b/posthog/hogql/database/schema/person_distinct_id_overrides.py @@ -0,0 +1,92 @@ +from typing import Dict, List +from posthog.hogql.ast import SelectQuery +from posthog.hogql.context import HogQLContext + +from posthog.hogql.database.argmax import argmax_select +from posthog.hogql.database.models import ( + Table, + IntegerDatabaseField, + StringDatabaseField, + BooleanDatabaseField, + LazyJoin, + LazyTable, + FieldOrTable, +) +from posthog.hogql.database.schema.persons import join_with_persons_table +from posthog.hogql.errors import HogQLException +from posthog.schema import HogQLQueryModifiers + +PERSON_DISTINCT_ID_OVERRIDES_FIELDS = { + "team_id": IntegerDatabaseField(name="team_id"), + "distinct_id": StringDatabaseField(name="distinct_id"), + "person_id": StringDatabaseField(name="person_id"), + "person": LazyJoin( + from_field=["person_id"], + join_table="persons", + join_function=join_with_persons_table, + ), +} + + +def select_from_person_distinct_id_overrides_table(requested_fields: Dict[str, List[str | int]]): + # Always include "person_id", as it's the key we use to make further joins, and it'd be great if it's available + if "person_id" not in requested_fields: + requested_fields = {**requested_fields, "person_id": ["person_id"]} + return argmax_select( + table_name="raw_person_distinct_id_overrides", + select_fields=requested_fields, + group_fields=["distinct_id"], + argmax_field="version", + deleted_field="is_deleted", + ) + + +def join_with_person_distinct_id_overrides_table( + from_table: str, + to_table: str, + requested_fields: Dict[str, List[str]], + context: HogQLContext, + node: SelectQuery, +): + from posthog.hogql import ast + + if not requested_fields: + raise HogQLException("No fields requested from person_distinct_id_overrides") + join_expr = ast.JoinExpr(table=select_from_person_distinct_id_overrides_table(requested_fields)) + join_expr.join_type = "LEFT OUTER JOIN" + join_expr.alias = to_table + join_expr.constraint = ast.JoinConstraint( + expr=ast.CompareOperation( + op=ast.CompareOperationOp.Eq, + left=ast.Field(chain=[from_table, "distinct_id"]), + right=ast.Field(chain=[to_table, "distinct_id"]), + ) + ) + return join_expr + + +class RawPersonDistinctIdOverridesTable(Table): + fields: Dict[str, FieldOrTable] = { + **PERSON_DISTINCT_ID_OVERRIDES_FIELDS, + "is_deleted": BooleanDatabaseField(name="is_deleted"), + "version": IntegerDatabaseField(name="version"), + } + + def to_printed_clickhouse(self, context): + return "person_distinct_id_overrides" + + def to_printed_hogql(self): + return "raw_person_distinct_id_overrides" + + +class PersonDistinctIdOverridesTable(LazyTable): + fields: Dict[str, FieldOrTable] = PERSON_DISTINCT_ID_OVERRIDES_FIELDS + + def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + return select_from_person_distinct_id_overrides_table(requested_fields) + + def to_printed_clickhouse(self, context): + return "person_distinct_id_overrides" + + def to_printed_hogql(self): + return "person_distinct_id_overrides" diff --git a/posthog/hogql/database/test/__snapshots__/test_database.ambr b/posthog/hogql/database/test/__snapshots__/test_database.ambr index db4dfc8f6df9f..63c2d16ce87aa 100644 --- a/posthog/hogql/database/test/__snapshots__/test_database.ambr +++ b/posthog/hogql/database/test/__snapshots__/test_database.ambr @@ -304,6 +304,31 @@ ] } ], + "person_distinct_id_overrides": [ + { + "key": "distinct_id", + "type": "string" + }, + { + "key": "person_id", + "type": "string" + }, + { + "key": "person", + "type": "lazy_table", + "table": "persons", + "fields": [ + "id", + "created_at", + "team_id", + "properties", + "is_identified", + "pdi", + "$virt_initial_referring_domain_type", + "$virt_initial_channel_type" + ] + } + ], "person_overrides": [ { "key": "old_person_id", @@ -790,6 +815,39 @@ "type": "integer" } ], + "raw_person_distinct_id_overrides": [ + { + "key": "distinct_id", + "type": "string" + }, + { + "key": "person_id", + "type": "string" + }, + { + "key": "person", + "type": "lazy_table", + "table": "persons", + "fields": [ + "id", + "created_at", + "team_id", + "properties", + "is_identified", + "pdi", + "$virt_initial_referring_domain_type", + "$virt_initial_channel_type" + ] + }, + { + "key": "is_deleted", + "type": "boolean" + }, + { + "key": "version", + "type": "integer" + } + ], "raw_person_overrides": [ { "key": "old_person_id", @@ -1155,6 +1213,31 @@ ] } ], + "person_distinct_id_overrides": [ + { + "key": "distinct_id", + "type": "string" + }, + { + "key": "person_id", + "type": "string" + }, + { + "key": "person", + "type": "lazy_table", + "table": "persons", + "fields": [ + "id", + "created_at", + "team_id", + "properties", + "is_identified", + "pdi", + "$virt_initial_referring_domain_type", + "$virt_initial_channel_type" + ] + } + ], "person_overrides": [ { "key": "old_person_id", @@ -1641,6 +1724,39 @@ "type": "integer" } ], + "raw_person_distinct_id_overrides": [ + { + "key": "distinct_id", + "type": "string" + }, + { + "key": "person_id", + "type": "string" + }, + { + "key": "person", + "type": "lazy_table", + "table": "persons", + "fields": [ + "id", + "created_at", + "team_id", + "properties", + "is_identified", + "pdi", + "$virt_initial_referring_domain_type", + "$virt_initial_channel_type" + ] + }, + { + "key": "is_deleted", + "type": "boolean" + }, + { + "key": "version", + "type": "integer" + } + ], "raw_person_overrides": [ { "key": "old_person_id", diff --git a/posthog/hogql/test/test_modifiers.py b/posthog/hogql/test/test_modifiers.py index eba1f5195ab3d..b2b0ef1e40630 100644 --- a/posthog/hogql/test/test_modifiers.py +++ b/posthog/hogql/test/test_modifiers.py @@ -74,6 +74,13 @@ def test_modifiers_persons_on_events_mode_mapping(self): "events.person_properties AS properties", "toTimeZone(events.person_created_at, %(hogql_val_1)s) AS created_at", ), + ( + PersonsOnEventsMode.v3_enabled, + "events.event AS event", + "if(not(empty(events__override.distinct_id)), events__override.person_id, events.person_id) AS id", + "events.person_properties AS properties", + "toTimeZone(events.person_created_at, %(hogql_val_0)s) AS created_at", + ), ] for mode, *expected in test_cases: diff --git a/posthog/schema.py b/posthog/schema.py index dc77da163db17..c88f8bf3f76de 100644 --- a/posthog/schema.py +++ b/posthog/schema.py @@ -418,6 +418,7 @@ class PersonsOnEventsMode(str, Enum): v1_enabled = "v1_enabled" v1_mixed = "v1_mixed" v2_enabled = "v2_enabled" + v3_enabled = "v3_enabled" class HogQLQueryModifiers(BaseModel): From 3bacde5dfa3a19933dfaded10f255e1939a63d5d Mon Sep 17 00:00:00 2001 From: ted kaemming <65315+tkaemming@users.noreply.github.com> Date: Fri, 22 Mar 2024 13:00:26 -0700 Subject: [PATCH 15/16] fix: Update `PersonDistinctIdOverridesTable` to be consistent with updated `LazyTable` interface (#21113) --- posthog/hogql/database/schema/person_distinct_id_overrides.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/posthog/hogql/database/schema/person_distinct_id_overrides.py b/posthog/hogql/database/schema/person_distinct_id_overrides.py index ae31440b10b7d..34df59655c24d 100644 --- a/posthog/hogql/database/schema/person_distinct_id_overrides.py +++ b/posthog/hogql/database/schema/person_distinct_id_overrides.py @@ -14,7 +14,6 @@ ) from posthog.hogql.database.schema.persons import join_with_persons_table from posthog.hogql.errors import HogQLException -from posthog.schema import HogQLQueryModifiers PERSON_DISTINCT_ID_OVERRIDES_FIELDS = { "team_id": IntegerDatabaseField(name="team_id"), @@ -82,7 +81,7 @@ def to_printed_hogql(self): class PersonDistinctIdOverridesTable(LazyTable): fields: Dict[str, FieldOrTable] = PERSON_DISTINCT_ID_OVERRIDES_FIELDS - def lazy_select(self, requested_fields: Dict[str, List[str | int]], modifiers: HogQLQueryModifiers): + def lazy_select(self, requested_fields: Dict[str, List[str | int]], context: HogQLContext, node: SelectQuery): return select_from_person_distinct_id_overrides_table(requested_fields) def to_printed_clickhouse(self, context): From ced62f45d1b9a4a530605969864aaf2c34fb4cef Mon Sep 17 00:00:00 2001 From: Zach Waterfield Date: Fri, 22 Mar 2024 14:46:52 -0600 Subject: [PATCH 16/16] chore: signup page footer support copy (#21089) * Remove slack from signup support methods * Update SignupContainer.tsx * Update UI snapshots for `chromium` (1) --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- .../scenes-other-signup--cloud--light.png | Bin 63485 -> 64643 bytes ...cenes-other-signup--self-hosted--light.png | Bin 62733 -> 63330 bytes ...s-other-signup--self-hosted-sso--light.png | Bin 70840 -> 71521 bytes .../authentication/signup/SignupContainer.tsx | 8 ++------ 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/frontend/__snapshots__/scenes-other-signup--cloud--light.png b/frontend/__snapshots__/scenes-other-signup--cloud--light.png index c527248055ffa4a131f6540dbcf48b9de1a055a8..05ee6352a0fad41d9d96e5804390b7a97cc74a1e 100644 GIT binary patch literal 64643 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

2O&+JSidI%xI{$GXWr{qS}a_76z^0L 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%0AI$BBk_3O7=Cnm&Ev)ga6+Hkpj=?<$WDFqdf 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%0AeQ$vMKc;|k0JN=l(+q67Ugbh%*p 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 QmYlPaa~_7w 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⪻eQ!n3U+SyH@ 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 literal 70840 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