From 9f0d9a8327cd0918ad968783b660358b4213ab80 Mon Sep 17 00:00:00 2001 From: David Newell Date: Tue, 18 Jun 2024 16:03:10 +0100 Subject: [PATCH 01/21] chore: cleanup css vars (#22974) --- .../lib/components/DateFilter/RollingDateRangeFilter.scss | 2 +- .../lib/components/DefinitionPopover/DefinitionPopover.scss | 2 +- frontend/src/lib/components/PayGateMini/PayGateMini.tsx | 6 +++--- frontend/src/lib/components/Sharing/SharingModal.scss | 2 +- .../TimeSensitiveAuthentication.tsx | 2 +- frontend/src/lib/lemon-ui/LemonMenu/LemonMenu.stories.tsx | 4 +++- frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss | 2 +- .../src/lib/lemon-ui/LemonSelect/LemonSelect.stories.tsx | 2 +- frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss | 2 +- frontend/src/queries/QueryEditor/QueryEditor.tsx | 2 +- .../DataTable/ColumnConfigurator/ColumnConfigurator.scss | 2 +- frontend/src/queries/nodes/DataTable/DataTable.scss | 2 +- .../InsightViz/PropertyGroupFilters/AndOrFilterSelect.tsx | 2 +- .../PropertyGroupFilters/PropertyGroupFilters.scss | 2 +- frontend/src/scenes/PreflightCheck/PreflightCheck.scss | 4 ++-- frontend/src/scenes/apps/ErrorDetailsModal.tsx | 4 ++-- frontend/src/scenes/billing/BillingProduct.tsx | 2 +- frontend/src/scenes/billing/BillingProductAddon.tsx | 2 +- frontend/src/scenes/billing/PlanComparison.tsx | 2 +- frontend/src/scenes/cohorts/Cohorts.scss | 2 +- frontend/src/scenes/experiments/Experiment.scss | 2 +- frontend/src/scenes/groups/GroupsIntroduction.tsx | 2 +- frontend/src/scenes/insights/EmptyStates/EmptyStates.tsx | 6 +++--- .../scenes/insights/filters/ActionFilter/ActionFilter.scss | 2 +- .../scenes/insights/views/Funnels/CorrelationMatrix.scss | 2 +- .../notebooks/Nodes/NotebookNodePersonFeed/Session.tsx | 2 +- frontend/src/scenes/notebooks/Notebook/Notebook.scss | 2 +- frontend/src/scenes/pipeline/PipelineNodeMetrics.tsx | 4 ++-- frontend/src/scenes/products/Products.tsx | 2 +- frontend/src/scenes/project-homepage/ProjectHomepage.scss | 2 +- .../src/scenes/session-recordings/player/PlayerMeta.scss | 2 +- .../player/inspector/PlayerInspectorControls.tsx | 2 +- .../player/inspector/PlayerInspectorList.tsx | 4 ++-- .../playlist/SessionRecordingsPlaylist.tsx | 2 +- .../playlist/SessionRecordingsPlaylistSettings.tsx | 2 +- frontend/src/scenes/trends/persons-modal/PersonsModal.tsx | 2 +- frontend/src/styles/antd.less | 2 +- frontend/src/styles/vars.scss | 2 -- 38 files changed, 47 insertions(+), 47 deletions(-) diff --git a/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss b/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss index 432c85858af609..9edf5ff154e5be 100644 --- a/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss +++ b/frontend/src/lib/components/DateFilter/RollingDateRangeFilter.scss @@ -12,7 +12,7 @@ transition: background 0.3s ease; &:hover { - background-color: var(--mid); + background-color: var(--bg-3000); } input::-webkit-outer-spin-button, diff --git a/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss b/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss index abc3ea434c470a..a03bd65c54b8e8 100644 --- a/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss +++ b/frontend/src/lib/components/DefinitionPopover/DefinitionPopover.scss @@ -102,7 +102,7 @@ } .DefinitionPopover { - background-color: var(--side); + background-color: var(--bg-3000); .DefinitionPopover__label { align-items: flex-start; diff --git a/frontend/src/lib/components/PayGateMini/PayGateMini.tsx b/frontend/src/lib/components/PayGateMini/PayGateMini.tsx index f251369c64732f..de33f34fbcc25c 100644 --- a/frontend/src/lib/components/PayGateMini/PayGateMini.tsx +++ b/frontend/src/lib/components/PayGateMini/PayGateMini.tsx @@ -157,7 +157,7 @@ function PayGateContent({
@@ -203,7 +203,7 @@ const renderUsageLimitMessage = ( .

-

+

Your current plan limit:{' '} {featureAvailableOnOrg.limit} {featureAvailableOnOrg.unit} @@ -262,7 +262,7 @@ const renderGateVariantMessage = ( const GrandfatheredMessage = (): JSX.Element => { return ( -

+

Your plan does not include this feature, but previously set settings may remain. Please upgrade your diff --git a/frontend/src/lib/components/Sharing/SharingModal.scss b/frontend/src/lib/components/Sharing/SharingModal.scss index fc7ad30d53ae9f..5a951374a00182 100644 --- a/frontend/src/lib/components/Sharing/SharingModal.scss +++ b/frontend/src/lib/components/Sharing/SharingModal.scss @@ -1,4 +1,4 @@ .SharingPreview { padding: 0.5rem; - background-color: var(--mid); + background-color: var(--bg-3000); } diff --git a/frontend/src/lib/components/TimeSensitiveAuthentication/TimeSensitiveAuthentication.tsx b/frontend/src/lib/components/TimeSensitiveAuthentication/TimeSensitiveAuthentication.tsx index f977f943754e73..4956230ddb1145 100644 --- a/frontend/src/lib/components/TimeSensitiveAuthentication/TimeSensitiveAuthentication.tsx +++ b/frontend/src/lib/components/TimeSensitiveAuthentication/TimeSensitiveAuthentication.tsx @@ -119,7 +119,7 @@ export function TimeSensitiveAuthenticationArea({ children }: { children: JSX.El }, []) return timeSensitiveAuthenticationRequired ? ( -

+

Re-authentication required

For security purposes, this area requires that you re-authenticate

diff --git a/frontend/src/lib/lemon-ui/LemonMenu/LemonMenu.stories.tsx b/frontend/src/lib/lemon-ui/LemonMenu/LemonMenu.stories.tsx index e67b7821ad30ce..f0b4ef79863951 100644 --- a/frontend/src/lib/lemon-ui/LemonMenu/LemonMenu.stories.tsx +++ b/frontend/src/lib/lemon-ui/LemonMenu/LemonMenu.stories.tsx @@ -100,7 +100,9 @@ NestedMenu.args = { ], }, ], - footer:
I am a custom footer!
, + footer: ( +
I am a custom footer!
+ ), }, { items: [ diff --git a/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss b/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss index 0d5661f54ea71e..73cea38b9ba47a 100644 --- a/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss +++ b/frontend/src/lib/lemon-ui/LemonRow/LemonRow.scss @@ -43,7 +43,7 @@ } &.LemonRow--status-muted { - background: var(--side); + background: var(--bg-3000); } &.LemonRow--disabled { diff --git a/frontend/src/lib/lemon-ui/LemonSelect/LemonSelect.stories.tsx b/frontend/src/lib/lemon-ui/LemonSelect/LemonSelect.stories.tsx index 20a8dd75435a18..d68bc0a3098b4a 100644 --- a/frontend/src/lib/lemon-ui/LemonSelect/LemonSelect.stories.tsx +++ b/frontend/src/lib/lemon-ui/LemonSelect/LemonSelect.stories.tsx @@ -62,7 +62,7 @@ SectionedOptions.args = { ), options: [{ value: 'tomato', label: 'Tomato??', disabled: true }], footer: ( -
+

I am a custom footer!
This might be a good time to tell you about our premium features... diff --git a/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss b/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss index debdb46ec27f9d..5c225d0f5f8de1 100644 --- a/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss +++ b/frontend/src/lib/lemon-ui/LemonTable/LemonTable.scss @@ -146,7 +146,7 @@ &.LemonTable__expansion { position: relative; - background: var(--side); + background: var(--bg-3000); > td { // Disable padding inside the expansion for better tailored placement of contents diff --git a/frontend/src/queries/QueryEditor/QueryEditor.tsx b/frontend/src/queries/QueryEditor/QueryEditor.tsx index 88026a6c7262c4..9b82fba450ef9c 100644 --- a/frontend/src/queries/QueryEditor/QueryEditor.tsx +++ b/frontend/src/queries/QueryEditor/QueryEditor.tsx @@ -57,7 +57,7 @@ export function QueryEditor(props: QueryEditorProps): JSX.Element {

diff --git a/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss b/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss index 7033d5e929863f..80cc09efab61a5 100644 --- a/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss +++ b/frontend/src/queries/nodes/DataTable/ColumnConfigurator/ColumnConfigurator.scss @@ -4,7 +4,7 @@ column-gap: 1rem; width: 700px; padding: 0.5rem; - background-color: var(--side); + background-color: var(--bg-3000); border-radius: var(--radius); @media (max-width: 960px) { diff --git a/frontend/src/queries/nodes/DataTable/DataTable.scss b/frontend/src/queries/nodes/DataTable/DataTable.scss index ae0f574e2a5f12..389eab98dab9a1 100644 --- a/frontend/src/queries/nodes/DataTable/DataTable.scss +++ b/frontend/src/queries/nodes/DataTable/DataTable.scss @@ -13,7 +13,7 @@ font-weight: 600; color: var(--muted); text-align: center; - background-color: var(--mid); + background-color: var(--bg-3000); } @keyframes DataTable__highlight { diff --git a/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/AndOrFilterSelect.tsx b/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/AndOrFilterSelect.tsx index 2d3ef56c692727..598420f8ba892c 100644 --- a/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/AndOrFilterSelect.tsx +++ b/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/AndOrFilterSelect.tsx @@ -73,7 +73,7 @@ const SelectOption = ({ title, description, value, selectedValue }: SelectOption
{value} diff --git a/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss b/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss index 8eface52ec75f8..e49053efb0ffcb 100644 --- a/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss +++ b/frontend/src/queries/nodes/InsightViz/PropertyGroupFilters/PropertyGroupFilters.scss @@ -1,7 +1,7 @@ .PropertyGroupFilters { .property-group { padding: 0.5rem; - background-color: var(--side); + background-color: var(--bg-3000); border-width: 1px; border-radius: var(--radius); } diff --git a/frontend/src/scenes/PreflightCheck/PreflightCheck.scss b/frontend/src/scenes/PreflightCheck/PreflightCheck.scss index 2d3485930e1a5b..26ea6aca9d1192 100644 --- a/frontend/src/scenes/PreflightCheck/PreflightCheck.scss +++ b/frontend/src/scenes/PreflightCheck/PreflightCheck.scss @@ -67,8 +67,8 @@ display: flex; align-items: center; justify-content: center; - background-color: var(--side); - border: 2px solid var(--mid); + background-color: var(--bg-3000); + border: 2px solid var(--bg-3000); p { margin-bottom: 0; diff --git a/frontend/src/scenes/apps/ErrorDetailsModal.tsx b/frontend/src/scenes/apps/ErrorDetailsModal.tsx index 5e9e373f6f3ce3..59d8d3521eead8 100644 --- a/frontend/src/scenes/apps/ErrorDetailsModal.tsx +++ b/frontend/src/scenes/apps/ErrorDetailsModal.tsx @@ -102,13 +102,13 @@ function CollapsibleSection(props: { const [isExpanded, setIsExpanded] = useState(props.defaultIsExpanded) return ( -
+
setIsExpanded(!isExpanded)} sideIcon={isExpanded ? : } title={isExpanded ? 'Show less' : 'Show more'} - className="bg-mid" + className="bg-bg-3000" > {props.title} diff --git a/frontend/src/scenes/billing/BillingProduct.tsx b/frontend/src/scenes/billing/BillingProduct.tsx index 215ddcd1efe844..7d48c0c2e079d7 100644 --- a/frontend/src/scenes/billing/BillingProduct.tsx +++ b/frontend/src/scenes/billing/BillingProduct.tsx @@ -94,7 +94,7 @@ export const BillingProduct = ({ product }: { product: BillingProductV2Type }): ref={ref} >
-
+
{getProductIcon(product.name, product.icon_key, 'text-2xl')}
diff --git a/frontend/src/scenes/billing/BillingProductAddon.tsx b/frontend/src/scenes/billing/BillingProductAddon.tsx index 57a9c2edb2803a..7456c4baedee18 100644 --- a/frontend/src/scenes/billing/BillingProductAddon.tsx +++ b/frontend/src/scenes/billing/BillingProductAddon.tsx @@ -70,7 +70,7 @@ export const BillingProductAddon = ({ addon }: { addon: BillingProductV2AddonTyp addon.plans?.find((plan) => plan.plan_key === 'addon-20240404-og-customers') return ( -
+
{getProductIcon(addon.name, addon.icon_key, 'text-2xl')}
diff --git a/frontend/src/scenes/billing/PlanComparison.tsx b/frontend/src/scenes/billing/PlanComparison.tsx index 61ce6803d5951a..42c627495c64e6 100644 --- a/frontend/src/scenes/billing/PlanComparison.tsx +++ b/frontend/src/scenes/billing/PlanComparison.tsx @@ -401,7 +401,7 @@ export const PlanComparison = ({
{getProductIcon( diff --git a/frontend/src/scenes/cohorts/Cohorts.scss b/frontend/src/scenes/cohorts/Cohorts.scss index 82992a1e15f7f1..3d6cc05cb56c3b 100644 --- a/frontend/src/scenes/cohorts/Cohorts.scss +++ b/frontend/src/scenes/cohorts/Cohorts.scss @@ -6,7 +6,7 @@ .cohort-recalculating { padding: 0.5rem 1rem; margin-top: 1rem; - background-color: var(--mid); + background-color: var(--bg-3000); border-radius: var(--radius); .ant-spin-spinning { diff --git a/frontend/src/scenes/experiments/Experiment.scss b/frontend/src/scenes/experiments/Experiment.scss index 5df078a37beced..0631a78f6a78bb 100644 --- a/frontend/src/scenes/experiments/Experiment.scss +++ b/frontend/src/scenes/experiments/Experiment.scss @@ -147,7 +147,7 @@ min-height: 320px; margin-top: 1rem; font-size: 24px; - background-color: var(--side); + background-color: var(--bg-3000); border: 1px solid var(--border); } diff --git a/frontend/src/scenes/groups/GroupsIntroduction.tsx b/frontend/src/scenes/groups/GroupsIntroduction.tsx index 385bdc8a0cd2b3..c2649df38bde78 100644 --- a/frontend/src/scenes/groups/GroupsIntroduction.tsx +++ b/frontend/src/scenes/groups/GroupsIntroduction.tsx @@ -32,7 +32,7 @@ export function GroupsIntroduction(): JSX.Element { export function GroupIntroductionFooter({ needsUpgrade }: { needsUpgrade: boolean }): JSX.Element { return ( -
+
{needsUpgrade ? ( <> Track usage of groups of users with Group Analytics.{' '} diff --git a/frontend/src/scenes/insights/EmptyStates/EmptyStates.tsx b/frontend/src/scenes/insights/EmptyStates/EmptyStates.tsx index 21f4b69d4d940b..9e3b25bc2bddc5 100644 --- a/frontend/src/scenes/insights/EmptyStates/EmptyStates.tsx +++ b/frontend/src/scenes/insights/EmptyStates/EmptyStates.tsx @@ -142,7 +142,7 @@ export function InsightLoadingStateWithLoadingBar({ )}

-
+
@@ -190,7 +190,7 @@ export function InsightLoadingState({

Crunching through hogloads of data...

-
+
@@ -231,7 +231,7 @@ export function InsightTimeoutState({ queryId }: { queryId?: string | null }): J

Your query took too long to complete

-
+
diff --git a/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss b/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss index 6c5b3dea1d24a0..7525560c3168b5 100644 --- a/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss +++ b/frontend/src/scenes/insights/filters/ActionFilter/ActionFilter.scss @@ -29,7 +29,7 @@ .ActionFilterRow-filters { padding: 0.5rem; - background-color: var(--side); + background-color: var(--bg-3000); border-bottom: 1px solid var(--border); } } diff --git a/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss b/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss index cb20c81271fb25..3a02cb817e0a67 100644 --- a/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss +++ b/frontend/src/scenes/insights/views/Funnels/CorrelationMatrix.scss @@ -35,7 +35,7 @@ font-weight: bold; color: var(--muted); text-transform: uppercase; - background-color: var(--mid); + background-color: var(--bg-3000); } tbody { diff --git a/frontend/src/scenes/notebooks/Nodes/NotebookNodePersonFeed/Session.tsx b/frontend/src/scenes/notebooks/Nodes/NotebookNodePersonFeed/Session.tsx index 9b51b5be558c21..4d6f24aa4af181 100644 --- a/frontend/src/scenes/notebooks/Nodes/NotebookNodePersonFeed/Session.tsx +++ b/frontend/src/scenes/notebooks/Nodes/NotebookNodePersonFeed/Session.tsx @@ -52,7 +52,7 @@ export const Session = ({ session }: SessionProps): JSX.Element => { } return ( -
+
+
setIsExpanded(!isExpanded)} sideIcon={isExpanded ? : } title={isExpanded ? 'Show less' : 'Show more'} - className="bg-mid" + className="bg-bg-3000" > {props.title} diff --git a/frontend/src/scenes/products/Products.tsx b/frontend/src/scenes/products/Products.tsx index 14007067a4a493..ed3ef4d1f63f93 100644 --- a/frontend/src/scenes/products/Products.tsx +++ b/frontend/src/scenes/products/Products.tsx @@ -88,7 +88,7 @@ export function Products(): JSX.Element { const { isFirstProductOnboarding } = useValues(onboardingLogic) return ( -
+
{isFirstProductOnboarding ? (

Where do you want to start?

diff --git a/frontend/src/scenes/project-homepage/ProjectHomepage.scss b/frontend/src/scenes/project-homepage/ProjectHomepage.scss index c18c105f2dee75..b338e74e04da03 100644 --- a/frontend/src/scenes/project-homepage/ProjectHomepage.scss +++ b/frontend/src/scenes/project-homepage/ProjectHomepage.scss @@ -46,6 +46,6 @@ justify-content: center; width: 100%; padding: 4rem; - background-color: var(--side); + background-color: var(--bg-3000); } } diff --git a/frontend/src/scenes/session-recordings/player/PlayerMeta.scss b/frontend/src/scenes/session-recordings/player/PlayerMeta.scss index e45fbc05a3340d..eacb352844e8cf 100644 --- a/frontend/src/scenes/session-recordings/player/PlayerMeta.scss +++ b/frontend/src/scenes/session-recordings/player/PlayerMeta.scss @@ -8,7 +8,7 @@ .PlayerMetaPersonProperties { padding: 0.5rem; overflow: auto; - background: var(--side); + background: var(--bg-3000); border-bottom: 1px solid transparent; } diff --git a/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorControls.tsx b/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorControls.tsx index 3b261aa18fb7ac..b023163e9fa9f4 100644 --- a/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorControls.tsx +++ b/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorControls.tsx @@ -108,7 +108,7 @@ export function PlayerInspectorControls({ } return ( -
+
diff --git a/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.tsx b/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.tsx index f7698153526c25..8575d5ebbfc16d 100644 --- a/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.tsx +++ b/frontend/src/scenes/session-recordings/player/inspector/PlayerInspectorList.tsx @@ -184,7 +184,7 @@ export function PlayerInspectorList(): JSX.Element { } return ( -
+
{!snapshotsLoaded ? (
Data will be shown once playback starts
) : items.length ? ( @@ -219,7 +219,7 @@ export function PlayerInspectorList(): JSX.Element { )} {syncScrollPaused && ( -
+
{ diff --git a/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx b/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx index 17ae678e317921..95d80a623be5c8 100644 --- a/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx +++ b/frontend/src/scenes/session-recordings/playlist/SessionRecordingsPlaylist.tsx @@ -241,7 +241,7 @@ function RecordingsLists(): JSX.Element {
{!notebookNode && showFilters ? ( -
+
+
diff --git a/frontend/src/scenes/trends/persons-modal/PersonsModal.tsx b/frontend/src/scenes/trends/persons-modal/PersonsModal.tsx index 31c557daa6bce0..cd1985d031832e 100644 --- a/frontend/src/scenes/trends/persons-modal/PersonsModal.tsx +++ b/frontend/src/scenes/trends/persons-modal/PersonsModal.tsx @@ -383,7 +383,7 @@ export function ActorRow({ actor, onOpenRecording, propertiesTimelineFilter }: A
{expanded ? ( -
+
Date: Tue, 18 Jun 2024 16:09:17 +0100 Subject: [PATCH 02/21] fix(insights): Fix breakdown limit for total values (#23036) --- .../test/__snapshots__/test_trends.ambr | 1673 +++-------------- .../test_trends_data_warehouse_query.ambr | 72 +- .../insights/trends/test/test_trends.py | 22 +- .../trends/test/test_trends_query_runner.py | 46 +- .../insights/trends/trends_query_builder.py | 58 +- ...t_session_recording_list_from_filters.ambr | 30 +- 6 files changed, 411 insertions(+), 1490 deletions(-) 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 91d53547b1942f..02c5905fc6118f 100644 --- a/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr +++ b/posthog/hogql_queries/insights/trends/test/__snapshots__/test_trends.ambr @@ -188,7 +188,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -220,6 +220,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -293,25 +294,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_by_group_props_person_on_events.3 - ''' - SELECT DISTINCT session_replay_events.session_id AS session_id - FROM session_replay_events - WHERE and(equals(session_replay_events.team_id, 2), ifNull(greaterOrEquals(toTimeZone(session_replay_events.min_first_timestamp, 'UTC'), minus(toDateTime64('2020-01-01 00:00:00.000000', 6, 'UTC'), toIntervalDay(21))), 0), in(session_replay_events.session_id, [''])) - LIMIT 100 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_by_group_props_with_person_filter_person_on_events ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -343,6 +330,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -355,52 +343,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_by_group_props_with_person_filter_person_on_events.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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, - groups.group_type_index AS index, - groups.group_key AS key - FROM groups - 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), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_filtering_with_properties_in_new_format ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -424,6 +371,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -440,7 +388,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -464,6 +412,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -476,89 +425,51 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_filtering_with_properties_in_new_format.2 - ''' - 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))) - GROUP BY value - ORDER BY count DESC, value DESC - LIMIT 26 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_breakdown_filtering_with_properties_in_new_format.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-22 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_weekly_active_users_aggregated ''' - SELECT count(DISTINCT actor_id) AS total, - breakdown_value AS breakdown_value + SELECT sum(total) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 26), 0), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM - (SELECT d.timestamp AS timestamp, - e.actor_id AS actor_id, - e.breakdown_value AS breakdown_value + (SELECT total AS total, + breakdown_value AS breakdown_value, + row_number() OVER ( + ORDER BY total DESC) AS row_number FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - e__pdi.person_id AS actor_id, - ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') 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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 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)) - GROUP BY d.timestamp, - e.actor_id, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) + (SELECT count(DISTINCT actor_id) AS total, + breakdown_value AS breakdown_value + FROM + (SELECT d.timestamp AS timestamp, + e.actor_id AS actor_id, + e.breakdown_value AS breakdown_value + FROM + (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp + FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC')))) AS numbers) AS d + CROSS JOIN + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e__pdi.person_id AS actor_id, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'key'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') 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, + person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + 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'), true), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 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)) + GROUP BY d.timestamp, + e.actor_id, + e.breakdown_value + ORDER BY d.timestamp ASC) + WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) + GROUP BY breakdown_value)) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, total DESC, + breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, @@ -569,81 +480,51 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_weekly_active_users_aggregated.1 - ''' - SELECT count(DISTINCT actor_id) AS total, - breakdown_value AS breakdown_value - FROM - (SELECT d.timestamp AS timestamp, - e.actor_id AS actor_id, - e.breakdown_value AS breakdown_value - FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - e__pdi.person_id AS actor_id, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 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)) - GROUP BY d.timestamp, - e.actor_id, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) - GROUP BY breakdown_value - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_weekly_active_users_aggregated_materialized ''' - SELECT count(DISTINCT actor_id) AS total, - breakdown_value AS breakdown_value + SELECT sum(total) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 26), 0), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM - (SELECT d.timestamp AS timestamp, - e.actor_id AS actor_id, - e.breakdown_value AS breakdown_value + (SELECT total AS total, + breakdown_value AS breakdown_value, + row_number() OVER ( + ORDER BY total DESC) AS row_number FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - e__pdi.person_id AS actor_id, - ifNull(nullIf(toString(nullIf(nullIf(e.mat_key, ''), 'null')), ''), '$$_posthog_breakdown_null_$$') 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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 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)) - GROUP BY d.timestamp, - e.actor_id, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) + (SELECT count(DISTINCT actor_id) AS total, + breakdown_value AS breakdown_value + FROM + (SELECT d.timestamp AS timestamp, + e.actor_id AS actor_id, + e.breakdown_value AS breakdown_value + FROM + (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp + FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC')))) AS numbers) AS d + CROSS JOIN + (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, + e__pdi.person_id AS actor_id, + ifNull(nullIf(toString(nullIf(nullIf(e.mat_key, ''), 'null')), ''), '$$_posthog_breakdown_null_$$') 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, + person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + 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'), true), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 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)) + GROUP BY d.timestamp, + e.actor_id, + e.breakdown_value + ORDER BY d.timestamp ASC) + WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) + GROUP BY breakdown_value)) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, total DESC, + breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, @@ -654,48 +535,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_weekly_active_users_aggregated_materialized.1 - ''' - SELECT count(DISTINCT actor_id) AS total, - breakdown_value AS breakdown_value - FROM - (SELECT d.timestamp AS timestamp, - e.actor_id AS actor_id, - e.breakdown_value AS breakdown_value - FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - e__pdi.person_id AS actor_id, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true), ifNull(greaterOrEquals(timestamp, minus(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 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)) - GROUP BY d.timestamp, - e.actor_id, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-11 23:59:59', 6, 'UTC'))), 0)) - GROUP BY breakdown_value - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_weekly_active_users_daily_based_on_action ''' @@ -720,7 +559,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -781,6 +620,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -793,81 +633,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_weekly_active_users_daily_based_on_action.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT counts AS total, - toStartOfDay(timestamp) AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT d.timestamp AS timestamp, - count(DISTINCT e.actor_id) AS counts, - e.breakdown_value AS breakdown_value - FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(7)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - e__pdi.person_id AS actor_id, - transform(ifNull(nullIf(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, - argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'name'), ''), 'null'), '^"|"$', '') AS properties___name - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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(and(equals(e.event, '$pageview'), and(or(ifNull(equals(e__pdi__person.properties___name, 'p1'), 0), ifNull(equals(e__pdi__person.properties___name, 'p2'), 0), ifNull(equals(e__pdi__person.properties___name, 'p3'), 0)), ifNull(in(e__pdi.person_id, - (SELECT cohortpeople.person_id AS person_id - FROM cohortpeople - WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2), equals(cohortpeople.version, 0)))), 0))), true), 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)) - GROUP BY d.timestamp, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))), 0))) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_with_filter_groups_person_on_events ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -899,6 +669,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -911,47 +682,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_with_filter_groups_person_on_events.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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, - groups.group_type_index AS index, - groups.group_key AS key - FROM groups - 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), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_breakdown_with_filter_groups_person_on_events_v2 ''' @@ -965,7 +695,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1004,6 +734,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -1016,59 +747,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_breakdown_with_filter_groups_person_on_events_v2.2 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-12 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0)) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - LEFT JOIN - (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(groups.group_properties, 'industry'), ''), 'null'), '^"|"$', ''), groups._timestamp) AS properties___industry, - groups.group_type_index AS index, - groups.group_key AS key - FROM groups - 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), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_dau_with_breakdown_filtering_with_sampling ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1099,6 +782,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -1115,7 +799,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1146,6 +830,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -1158,63 +843,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.2 - ''' - 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'))) - GROUP BY value - ORDER BY count DESC, value DESC - LIMIT 26 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_dau_with_breakdown_filtering_with_sampling.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT e__pdi.person_id) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_filter_events_by_precalculated_cohort ''' @@ -1518,7 +1146,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1577,6 +1205,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -1589,79 +1218,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_mau_with_breakdown_filtering_and_prop_filter.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT counts AS total, - toStartOfDay(timestamp) AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT d.timestamp AS timestamp, - count(DISTINCT e.actor_id) AS counts, - e.breakdown_value AS breakdown_value - FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(30)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - e__pdi.person_id AS actor_id, - transform(ifNull(nullIf(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, - argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$some_prop'), ''), 'null'), '^"|"$', '') AS `properties___$some_prop`, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'filter_prop'), ''), 'null'), '^"|"$', '') AS properties___filter_prop - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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), true), 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)) - GROUP BY d.timestamp, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0))) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_mau_with_breakdown_filtering_and_prop_filter_poe_v2 ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1708,6 +1269,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -1720,62 +1282,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_mau_with_breakdown_filtering_and_prop_filter_poe_v2.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT counts AS total, - toStartOfDay(timestamp) AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT d.timestamp AS timestamp, - count(DISTINCT e.actor_id) AS counts, - e.breakdown_value AS breakdown_value - FROM - (SELECT minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), toIntervalDay(numbers.number)) AS timestamp - FROM numbers(dateDiff('day', minus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(30)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC')))) AS numbers) AS d - CROSS JOIN - (SELECT toTimeZone(e.timestamp, 'UTC') AS timestamp, - if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id) AS actor_id, - transform(ifNull(nullIf(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_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0)) AS e__override ON equals(e.distinct_id, e__override.distinct_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), true), 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)) - GROUP BY d.timestamp, - e.breakdown_value - ORDER BY d.timestamp ASC) - WHERE and(ifNull(greaterOrEquals(timestamp, toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(timestamp, assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0))) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_non_deterministic_timezones ''' SELECT arrayMap(number -> plus(toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2022-10-31 00:00:00', 6, 'US/Pacific')), 0), toIntervalWeek(number)), range(0, plus(coalesce(dateDiff('week', toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2022-10-31 00:00:00', 6, 'US/Pacific')), 0), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2022-11-30 23:59:59', 6, 'US/Pacific')), 0))), 1))) AS date, @@ -1827,7 +1333,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1851,69 +1357,27 @@ 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'))), and(equals(e.event, 'sign up'), ifNull(in(e__pdi.person_id, - (SELECT cohortpeople.person_id AS person_id - FROM cohortpeople - WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2), equals(cohortpeople.version, 0)))), 0)), true) - 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 arraySum(total) DESC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288, - max_bytes_before_external_group_by=0 - ''' -# --- -# name: TestTrends.test_person_filtering_in_cohort_in_action.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'))), and(equals(e.event, 'sign up'), ifNull(in(e__pdi.person_id, - (SELECT cohortpeople.person_id AS person_id - FROM cohortpeople - WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2), equals(cohortpeople.version, 0)))), 0)), true) + (SELECT cohortpeople.person_id AS person_id + FROM cohortpeople + WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2), equals(cohortpeople.version, 0)))), 0)), true) + GROUP BY day_start, + breakdown_value) GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) + breakdown_value + ORDER BY day_start ASC, breakdown_value ASC) + GROUP BY breakdown_value + ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestTrends.test_person_filtering_in_cohort_in_action_poe_v2 @@ -1940,7 +1404,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -1974,6 +1438,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -1986,49 +1451,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_person_filtering_in_cohort_in_action_poe_v2.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0)) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), and(equals(e.event, 'sign up'), ifNull(in(if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), - (SELECT cohortpeople.person_id AS person_id - FROM cohortpeople - WHERE and(equals(cohortpeople.team_id, 2), equals(cohortpeople.cohort_id, 2), equals(cohortpeople.version, 0)))), 0)), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_person_property_filtering ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, @@ -2601,7 +2023,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -2632,6 +2054,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -2644,46 +2067,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_timezones_daily.5 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT e__pdi.person_id) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_timezones_daily_minus_utc ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix'))))), 1))) AS date, @@ -2823,7 +2206,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -2854,6 +2237,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -2866,46 +2250,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_timezones_daily_minus_utc.5 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'America/Phoenix'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'America/Phoenix'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT e__pdi.person_id) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'America/Phoenix')) AS day_start, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_timezones_daily_plus_utc ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo'))))), 1))) AS date, @@ -3045,7 +2389,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -3076,6 +2420,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -3088,46 +2433,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_timezones_daily_plus_utc.5 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-29 00:00:00', 6, 'Asia/Tokyo'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 23:59:59', 6, 'Asia/Tokyo'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT e__pdi.person_id) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'Asia/Tokyo')) AS day_start, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_timezones_hourly_relative_from ''' SELECT arrayMap(number -> plus(toStartOfHour(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 00:00:00', 6, 'UTC'))), toIntervalHour(number)), range(0, plus(coalesce(dateDiff('hour', toStartOfHour(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 00:00:00', 6, 'UTC'))), toStartOfHour(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-05 10:59:59', 6, 'UTC'))))), 1))) AS date, @@ -3477,7 +2782,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -3521,6 +2826,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -3537,7 +2843,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -3581,6 +2887,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -3593,96 +2900,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trend_breakdown_user_props_with_filter_with_partial_property_pushdowns.2 - ''' - SELECT toString(e__pdi__person.properties___email) AS value, - count(e.uuid) AS count - FROM events AS e - INNER JOIN - (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, - argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$os'), ''), 'null'), '^"|"$', '') AS `properties___$os`, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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(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')))), 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-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)))) - GROUP BY value - ORDER BY count DESC, value DESC - LIMIT 26 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_trend_breakdown_user_props_with_filter_with_partial_property_pushdowns.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-07-01 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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, - argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, 'email'), ''), 'null'), '^"|"$', '') AS properties___email, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$os'), ''), 'null'), '^"|"$', '') AS `properties___$os`, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$browser'), ''), 'null'), '^"|"$', '') AS `properties___$browser` - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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)), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_trends_aggregate_by_distinct_id ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))))), 1))) AS date, @@ -3759,7 +2976,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -3801,6 +3018,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -3897,7 +3115,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -3921,6 +3139,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -3933,56 +3152,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_aggregate_by_distinct_id.6 - ''' - 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'))) - GROUP BY value - ORDER BY count DESC, value DESC - LIMIT 26 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_trends_aggregate_by_distinct_id.7 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-24 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-31 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT e.distinct_id) AS total, - toStartOfDay(toTimeZone(e.timestamp, 'UTC')) AS day_start, - transform(ifNull(nullIf(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'), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_trends_any_event_total_count ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, @@ -4041,7 +3210,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayFill(x -> ifNull(greater(x, 0), 0), arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -4078,6 +3247,7 @@ ORDER BY day_start ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -4090,57 +3260,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_breakdown_cumulative.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayFill(x -> ifNull(greater(x, 0), 0), arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date)) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT day_start AS day_start, - sum(count) OVER (PARTITION BY breakdown_value - ORDER BY day_start ASC) AS count, - breakdown_value AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT e__pdi.person_id) AS total, - min(toStartOfDay(toTimeZone(e.timestamp, 'UTC'))) AS day_start, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true) - GROUP BY e__pdi.person_id, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - ORDER BY day_start ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_trends_breakdown_cumulative_poe_v2 ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayFill(x -> ifNull(greater(x, 0), 0), arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -4174,72 +3298,27 @@ GROUP BY day_start, breakdown_value ORDER BY day_start ASC, breakdown_value ASC) - ORDER BY day_start ASC) - GROUP BY breakdown_value - ORDER BY arraySum(total) DESC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288, - max_bytes_before_external_group_by=0 - ''' -# --- -# name: TestTrends.test_trends_breakdown_cumulative_poe_v2.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayFill(x -> ifNull(greater(x, 0), 0), arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date)) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT day_start AS day_start, - sum(count) OVER (PARTITION BY breakdown_value - ORDER BY day_start ASC) AS count, - breakdown_value AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, - min(toStartOfDay(toTimeZone(e.timestamp, 'UTC'))) AS day_start, - transform(ifNull(nullIf(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_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0)) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), true) - GROUP BY if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - ORDER BY day_start ASC) + ORDER BY day_start ASC) + GROUP BY breakdown_value + ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestTrends.test_trends_breakdown_normalize_url ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayFill(x -> ifNull(greater(x, 0), 0), arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -4278,6 +3357,7 @@ ORDER BY day_start ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -4290,74 +3370,38 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_breakdown_normalize_url.1 +# name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayFill(x -> ifNull(greater(x, 0), 0), arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date)) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value + SELECT sum(total) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 26), 0), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM - (SELECT day_start AS day_start, - sum(count) OVER (PARTITION BY breakdown_value - ORDER BY day_start ASC) AS count, - breakdown_value AS breakdown_value + (SELECT total AS total, + breakdown_value AS breakdown_value, + row_number() OVER ( + ORDER BY total DESC) AS row_number FROM - (SELECT sum(total) AS count, - day_start AS day_start, + (SELECT quantile(0.5)(session_duration) AS total, breakdown_value AS breakdown_value FROM - (SELECT count(DISTINCT if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id)) AS total, - min(toStartOfDay(toTimeZone(e.timestamp, 'UTC'))) AS day_start, - transform(ifNull(nullIf(toString(if(empty(trim(TRAILING '/?#' - FROM replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', ''))), '/', trim(TRAILING '/?#' - FROM replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$current_url'), ''), 'null'), '^"|"$', '')))), ''), '$$_posthog_breakdown_null_$$'), ['http://hogflix/first', 'http://hogflix/second'], ['http://hogflix/first', 'http://hogflix/second'], '$$_posthog_breakdown_other_$$') AS breakdown_value + (SELECT any(e__session.`$session_duration`) AS session_duration, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value FROM events AS e SAMPLE 1 - LEFT OUTER JOIN - (SELECT argMax(person_distinct_id_overrides.person_id, person_distinct_id_overrides.version) AS person_id, - person_distinct_id_overrides.distinct_id AS distinct_id - FROM person_distinct_id_overrides - WHERE equals(person_distinct_id_overrides.team_id, 2) - GROUP BY person_distinct_id_overrides.distinct_id - HAVING ifNull(equals(argMax(person_distinct_id_overrides.is_deleted, person_distinct_id_overrides.version), 0), 0)) AS e__override ON equals(e.distinct_id, e__override.distinct_id) - WHERE and(equals(e.team_id, 2), greaterOrEquals(toTimeZone(e.timestamp, 'UTC'), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), lessOrEquals(toTimeZone(e.timestamp, 'UTC'), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), equals(e.event, 'sign up'), true) - GROUP BY if(not(empty(e__override.distinct_id)), e__override.person_id, e.person_id), - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - ORDER BY day_start ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown - ''' - SELECT quantile(0.5)(session_duration) AS total, - breakdown_value AS breakdown_value - FROM - (SELECT any(e__session.`$session_duration`) AS session_duration, - ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM events AS e SAMPLE 1 - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.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'), true) - GROUP BY e.`$session_id`, - breakdown_value - ORDER BY 1 DESC, breakdown_value DESC) + LEFT JOIN + (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, + sessions.session_id AS session_id + FROM sessions + WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) + GROUP BY sessions.session_id, + sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.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'), true) + GROUP BY e.`$session_id`, + breakdown_value + ORDER BY 1 DESC, breakdown_value DESC) + GROUP BY breakdown_value)) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, total DESC, + breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, @@ -4370,24 +3414,36 @@ # --- # name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown.1 ''' - SELECT quantile(0.5)(session_duration) AS total, - breakdown_value AS breakdown_value + SELECT sum(total) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 26), 0), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM - (SELECT any(e__session.`$session_duration`) AS session_duration, - ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM events AS e SAMPLE 1 - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.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'), true) - GROUP BY e.`$session_id`, - breakdown_value - ORDER BY 1 DESC, breakdown_value DESC) + (SELECT total AS total, + breakdown_value AS breakdown_value, + row_number() OVER ( + ORDER BY total DESC) AS row_number + FROM + (SELECT quantile(0.5)(session_duration) AS total, + breakdown_value AS breakdown_value + FROM + (SELECT any(e__session.`$session_duration`) AS session_duration, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value + FROM events AS e SAMPLE 1 + LEFT JOIN + (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, + sessions.session_id AS session_id + FROM sessions + WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) + GROUP BY sessions.session_id, + sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.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'), true) + GROUP BY e.`$session_id`, + breakdown_value + ORDER BY 1 DESC, breakdown_value DESC) + GROUP BY breakdown_value)) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, total DESC, + breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, @@ -4398,58 +3454,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown.2 - ''' - SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, - max(e__session.`$session_duration`) AS count - FROM events AS e - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.session_id) - 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'))) - GROUP BY value - ORDER BY count DESC, value DESC - LIMIT 26 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_trends_breakdown_with_session_property_single_aggregate_math_and_breakdown.3 - ''' - SELECT quantile(0.5)(session_duration) AS total, - breakdown_value AS breakdown_value - FROM - (SELECT any(e__session.`$session_duration`) AS session_duration, - transform(ifNull(nullIf(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 - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.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'), true) - GROUP BY e.`$session_id`, - breakdown_value) - GROUP BY breakdown_value - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_trends_compare_day_interval_relative_range ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, @@ -4587,26 +3591,38 @@ # --- # name: TestTrends.test_trends_count_per_user_average_aggregated_with_event_property_breakdown_with_sampling ''' - SELECT total AS total, - breakdown_value AS breakdown_value + SELECT sum(total) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 26), 0), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM - (SELECT avg(total) AS total, - breakdown_value AS breakdown_value + (SELECT total AS total, + breakdown_value AS breakdown_value, + row_number() OVER ( + ORDER BY total DESC) AS row_number FROM - (SELECT count(e.uuid) AS total, - ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') 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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true), 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) + (SELECT total AS total, + breakdown_value AS breakdown_value + FROM + (SELECT avg(total) AS total, + breakdown_value AS breakdown_value + FROM + (SELECT count(e.uuid) AS total, + ifNull(nullIf(toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, 'color'), ''), 'null'), '^"|"$', '')), ''), '$$_posthog_breakdown_null_$$') 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, + person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + 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'), true), 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))) + WHERE isNotNull(breakdown_value) + GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, total DESC, + breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, @@ -4617,37 +3633,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_count_per_user_average_aggregated_with_event_property_breakdown_with_sampling.1 - ''' - SELECT total AS total, - breakdown_value AS breakdown_value - FROM - (SELECT avg(total) AS total, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.uuid) AS total, - transform(ifNull(nullIf(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, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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'), true), 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) - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_trends_count_per_user_average_daily ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-07 23:59:59', 6, 'UTC'))))), 1))) AS date, @@ -4864,42 +3849,54 @@ # --- # name: TestTrends.test_trends_person_breakdown_with_session_property_single_aggregate_math_and_breakdown ''' - SELECT quantile(0.5)(session_duration) AS total, - breakdown_value AS breakdown_value + SELECT sum(total) AS total, + if(ifNull(ifNull(greaterOrEquals(row_number, 26), 0), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM - (SELECT any(e__session.`$session_duration`) AS session_duration, - ifNull(nullIf(toString(e__pdi__person.`properties___$some_prop`), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM events AS e SAMPLE 1 - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.session_id) - INNER JOIN - (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, - argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$some_prop'), ''), 'null'), '^"|"$', '') AS `properties___$some_prop` - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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'), true) - GROUP BY e.`$session_id`, - breakdown_value - ORDER BY 1 DESC, breakdown_value DESC) + (SELECT total AS total, + breakdown_value AS breakdown_value, + row_number() OVER ( + ORDER BY total DESC) AS row_number + FROM + (SELECT quantile(0.5)(session_duration) AS total, + breakdown_value AS breakdown_value + FROM + (SELECT any(e__session.`$session_duration`) AS session_duration, + ifNull(nullIf(toString(e__pdi__person.`properties___$some_prop`), ''), '$$_posthog_breakdown_null_$$') AS breakdown_value + FROM events AS e SAMPLE 1 + LEFT JOIN + (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, + sessions.session_id AS session_id + FROM sessions + WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) + GROUP BY sessions.session_id, + sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.session_id) + INNER JOIN + (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, + argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, + person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + 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) + LEFT JOIN + (SELECT person.id AS id, + replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$some_prop'), ''), 'null'), '^"|"$', '') AS `properties___$some_prop` + FROM person + WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), + (SELECT person.id AS id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 2) + GROUP BY person.id + HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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'), true) + GROUP BY e.`$session_id`, + breakdown_value + ORDER BY 1 DESC, breakdown_value DESC) + GROUP BY breakdown_value)) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value + ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, total DESC, + breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, max_execution_time=60, allow_experimental_object_type=1, @@ -4910,52 +3907,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_person_breakdown_with_session_property_single_aggregate_math_and_breakdown.1 - ''' - SELECT quantile(0.5)(session_duration) AS total, - breakdown_value AS breakdown_value - FROM - (SELECT any(e__session.`$session_duration`) AS session_duration, - transform(ifNull(nullIf(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 - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0)), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.session_id) - INNER JOIN - (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS e__pdi___person_id, - argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, - person_distinct_id2.distinct_id AS distinct_id - FROM person_distinct_id2 - 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) - LEFT JOIN - (SELECT person.id AS id, - replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, '$some_prop'), ''), 'null'), '^"|"$', '') AS `properties___$some_prop` - FROM person - WHERE and(equals(person.team_id, 2), ifNull(in(tuple(person.id, person.version), - (SELECT person.id AS id, max(person.version) AS version - FROM person - WHERE equals(person.team_id, 2) - GROUP BY person.id - HAVING and(ifNull(equals(argMax(person.is_deleted, person.version), 0), 0), ifNull(less(argMax(person.created_at, person.version), plus(now64(6, 'UTC'), toIntervalDay(1))), 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'), true) - GROUP BY e.`$session_id`, - breakdown_value) - GROUP BY breakdown_value - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_trends_with_hogql_math ''' SELECT arrayMap(number -> plus(toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0), toIntervalWeek(number)), range(0, plus(coalesce(dateDiff('week', toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC')), 0))), 1))) AS date, @@ -5119,7 +4070,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0), toIntervalWeek(number)), range(0, plus(coalesce(dateDiff('week', toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')), 0), toStartOfWeek(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC')), 0))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -5158,6 +4109,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -5174,7 +4126,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -5213,6 +4165,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 50000 SETTINGS readonly=2, @@ -5225,78 +4178,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrends.test_trends_with_session_property_total_volume_math_with_breakdowns.2 - ''' - SELECT toString(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(e.properties, '$some_property'), ''), 'null'), '^"|"$', '')) AS value, - max(e__session.`$session_duration`) AS count - FROM events AS e - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.session_id) - 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'))) - GROUP BY value - ORDER BY count DESC, value DESC - LIMIT 26 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- -# name: TestTrends.test_trends_with_session_property_total_volume_math_with_breakdowns.3 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT quantile(0.5)(session_duration) AS total, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT any(e__session.`$session_duration`) AS session_duration, - transform(ifNull(nullIf(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 - LEFT JOIN - (SELECT dateDiff('second', min(sessions.min_timestamp), max(sessions.max_timestamp)) AS `$session_duration`, - sessions.session_id AS session_id - FROM sessions - WHERE and(equals(sessions.team_id, 2), ifNull(greaterOrEquals(plus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2019-12-28 00:00:00', 6, 'UTC')))), 0), ifNull(lessOrEquals(minus(toTimeZone(sessions.min_timestamp, 'UTC'), toIntervalDay(3)), assumeNotNull(parseDateTime64BestEffortOrNull('2020-01-04 23:59:59', 6, 'UTC'))), 0)) - GROUP BY sessions.session_id, - sessions.session_id) AS e__session ON equals(e.`$session_id`, e__session.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'), true) - GROUP BY day_start, - e.`$session_id`, - breakdown_value, - day_start) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 50000 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrends.test_weekly_active_users_aggregated_range_narrower_than_week ''' SELECT count(DISTINCT actor_id) AS total 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 09625ed9a847c1..59d0c6f5c27814 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 @@ -3,7 +3,7 @@ ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -27,6 +27,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 100 SETTINGS readonly=2, @@ -39,44 +40,11 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrendsDataWarehouseQuery.test_trends_breakdown.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.id) AS total, - toStartOfDay(toTimeZone(e.created, 'UTC')) AS day_start, - transform(ifNull(nullIf(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(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), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 100 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrendsDataWarehouseQuery.test_trends_breakdown_with_property ''' SELECT groupArray(1)(date)[1] AS date, arrayFold((acc, x) -> arrayMap(i -> plus(acc[i], x[i]), range(1, plus(length(date), 1))), groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0))) AS total, - if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', breakdown_value) AS breakdown_value + if(ifNull(greaterOrEquals(row_number, 25), 0), '$$_posthog_breakdown_other_$$', toString(breakdown_value)) AS breakdown_value FROM (SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))))), 1))) AS date, arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) @@ -100,6 +68,7 @@ ORDER BY day_start ASC, breakdown_value ASC) GROUP BY breakdown_value ORDER BY arraySum(total) DESC, breakdown_value ASC) + WHERE isNotNull(breakdown_value) GROUP BY breakdown_value ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)) ASC, arraySum(total) DESC, breakdown_value ASC LIMIT 100 SETTINGS readonly=2, @@ -112,39 +81,6 @@ max_bytes_before_external_group_by=0 ''' # --- -# name: TestTrendsDataWarehouseQuery.test_trends_breakdown_with_property.1 - ''' - SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))))), 1))) AS date, - arrayMap(_match_date -> arraySum(arraySlice(groupArray(count), indexOf(groupArray(day_start) AS _days_for_count, _match_date) AS _index, plus(minus(arrayLastIndex(x -> ifNull(equals(x, _match_date), isNull(x) - and isNull(_match_date)), _days_for_count), _index), 1))), date) AS total, - ifNull(toString(breakdown_value), '$$_posthog_breakdown_null_$$') AS breakdown_value - FROM - (SELECT sum(total) AS count, - day_start AS day_start, - breakdown_value AS breakdown_value - FROM - (SELECT count(e.id) AS total, - toStartOfDay(toTimeZone(e.created, 'UTC')) AS day_start, - transform(ifNull(nullIf(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(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), equals(e.prop_1, 'a'), true) - GROUP BY day_start, - breakdown_value) - GROUP BY day_start, - breakdown_value - ORDER BY day_start ASC, breakdown_value ASC) - GROUP BY breakdown_value - ORDER BY if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_other_$$'), 0), 2, if(ifNull(equals(breakdown_value, '$$_posthog_breakdown_null_$$'), 0), 1, 0)), - arraySum(total) DESC, breakdown_value ASC - LIMIT 100 SETTINGS readonly=2, - max_execution_time=60, - allow_experimental_object_type=1, - format_csv_allow_double_quotes=0, - max_ast_elements=1000000, - max_expanded_ast_elements=1000000, - max_query_size=524288 - ''' -# --- # name: TestTrendsDataWarehouseQuery.test_trends_data_warehouse ''' SELECT arrayMap(number -> plus(toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toIntervalDay(number)), range(0, plus(coalesce(dateDiff('day', toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-01 00:00:00', 6, 'UTC'))), toStartOfDay(assumeNotNull(parseDateTime64BestEffortOrNull('2023-01-07 23:59:59', 6, 'UTC'))))), 1))) AS date, diff --git a/posthog/hogql_queries/insights/trends/test/test_trends.py b/posthog/hogql_queries/insights/trends/test/test_trends.py index c3838fa8fd63c9..fa288cea532c2f 100644 --- a/posthog/hogql_queries/insights/trends/test/test_trends.py +++ b/posthog/hogql_queries/insights/trends/test/test_trends.py @@ -1604,7 +1604,7 @@ def test_trends_breakdown_with_session_property_single_aggregate_math_and_breakd # empty has: 1 seconds self.assertEqual( [resp["breakdown_value"] for resp in daily_response], - ["value1", "value2", "$$_posthog_breakdown_null_$$"], + ["value2", "value1", "$$_posthog_breakdown_null_$$"], ) self.assertEqual(sorted([resp["aggregated_value"] for resp in daily_response]), sorted([12.5, 10, 1])) @@ -6499,9 +6499,9 @@ def test_breakdown_filtering_bar_chart_by_value(self): self.team, ) - self.assertEqual(response[0]["aggregated_value"], 2) + self.assertEqual(response[0]["aggregated_value"], 1) self.assertEqual(response[1]["aggregated_value"], 1) - self.assertEqual(response[2]["aggregated_value"], 1) # the events without breakdown value + self.assertEqual(response[2]["aggregated_value"], 2) # the events without breakdown value self.assertEqual(response[0]["days"], []) @also_test_with_materialized_columns(person_properties=["key", "key_2"], verify_no_jsonextract=False) @@ -7662,11 +7662,11 @@ def test_trends_count_per_user_average_aggregated_with_event_property_breakdown( ) assert len(daily_response) == 3 - assert daily_response[0]["breakdown_value"] == "blue" - assert daily_response[1]["breakdown_value"] == "red" + assert daily_response[0]["breakdown_value"] == "red" + assert daily_response[1]["breakdown_value"] == "blue" assert daily_response[2]["breakdown_value"] == "$$_posthog_breakdown_null_$$" - assert daily_response[0]["aggregated_value"] == 1.0 # blue - assert daily_response[1]["aggregated_value"] == 2.0 # red + assert daily_response[0]["aggregated_value"] == 2.0 # red + assert daily_response[1]["aggregated_value"] == 1.0 # blue assert daily_response[2]["aggregated_value"] == 1.0 # $$_posthog_breakdown_null_$$ @snapshot_clickhouse_queries @@ -7689,11 +7689,11 @@ def test_trends_count_per_user_average_aggregated_with_event_property_breakdown_ ) assert len(daily_response) == 3 - assert daily_response[0]["breakdown_value"] == "blue" - assert daily_response[1]["breakdown_value"] == "red" + assert daily_response[0]["breakdown_value"] == "red" + assert daily_response[1]["breakdown_value"] == "blue" assert daily_response[2]["breakdown_value"] == "$$_posthog_breakdown_null_$$" - assert daily_response[0]["aggregated_value"] == 1.0 # blue - assert daily_response[1]["aggregated_value"] == 2.0 # red + assert daily_response[0]["aggregated_value"] == 2.0 # red + assert daily_response[1]["aggregated_value"] == 1.0 # blue assert daily_response[2]["aggregated_value"] == 1.0 # $$_posthog_breakdown_null_$$ # TODO: Add support for avg_count by group indexes (see this Slack thread for more context: https://posthog.slack.com/archives/C0368RPHLQH/p1700484174374229) 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 5ac3c588fd9703..627ee7f5a6ee94 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 @@ -1491,6 +1491,22 @@ def test_breakdown_values_limit(self): ) self.assertEqual(len(response.results), 11) + # Now hide other aggregation + response = self._run_trends_query( + "2020-01-09", + "2020-01-20", + IntervalType.DAY, + [EventsNode(event="$pageview")], + TrendsFilter(display=ChartDisplayType.ACTIONS_LINE_GRAPH), + BreakdownFilter( + breakdown="breakdown_value", + breakdown_type=BreakdownType.EVENT, + breakdown_limit=10, + breakdown_hide_other_aggregation=True, + ), + ) + self.assertEqual(len(response.results), 10) + response = self._run_trends_query( "2020-01-09", "2020-01-20", @@ -1502,6 +1518,34 @@ def test_breakdown_values_limit(self): ) self.assertEqual(len(response.results), 30) + # Test actions table - it shows total values + + response = self._run_trends_query( + "2020-01-09", + "2020-01-20", + IntervalType.DAY, + [EventsNode(event="$pageview")], + TrendsFilter(display=ChartDisplayType.ACTIONS_TABLE), + BreakdownFilter(breakdown="breakdown_value", breakdown_type=BreakdownType.EVENT, breakdown_limit=10), + ) + self.assertEqual(len(response.results), 11) + + # Now hide other aggregation + response = self._run_trends_query( + "2020-01-09", + "2020-01-20", + IntervalType.DAY, + [EventsNode(event="$pageview")], + TrendsFilter(display=ChartDisplayType.ACTIONS_TABLE), + BreakdownFilter( + breakdown="breakdown_value", + breakdown_type=BreakdownType.EVENT, + breakdown_limit=10, + breakdown_hide_other_aggregation=True, + ), + ) + self.assertEqual(len(response.results), 10) + def test_breakdown_values_unknown_property(self): # same as above test, just without creating the property definition for value in list(range(30)): @@ -2128,8 +2172,8 @@ def test_to_actors_query_options_bar_value(self): assert response.breakdown == [ BreakdownItem(label="Chrome", value="Chrome"), BreakdownItem(label="Firefox", value="Firefox"), - BreakdownItem(label="Safari", value="Safari"), BreakdownItem(label="Edge", value="Edge"), + BreakdownItem(label="Safari", value="Safari"), ] @patch("posthog.hogql.query.sync_execute", wraps=sync_execute) diff --git a/posthog/hogql_queries/insights/trends/trends_query_builder.py b/posthog/hogql_queries/insights/trends/trends_query_builder.py index 2bfc397da03c42..8ef3c97dd73e50 100644 --- a/posthog/hogql_queries/insights/trends/trends_query_builder.py +++ b/posthog/hogql_queries/insights/trends/trends_query_builder.py @@ -61,7 +61,8 @@ def build_query(self) -> ast.SelectQuery | ast.SelectUnionQuery: if self._trends_display.is_total_value(): events_query = self._get_events_subquery(False, is_actors_query=False, breakdown=breakdown) - return events_query + wrapper_query = self._get_wrapper_query(events_query, breakdown=breakdown) + return wrapper_query else: event_query = self._get_events_subquery(False, is_actors_query=False, breakdown=breakdown) @@ -70,6 +71,49 @@ def build_query(self) -> ast.SelectQuery | ast.SelectUnionQuery: return full_query + def _get_breakdown_hide_others(self) -> bool: + return ( + self.query.breakdownFilter.breakdown_hide_other_aggregation or False + if self.query.breakdownFilter + else False + ) + + def _get_wrapper_query( + self, events_query: ast.SelectQuery, breakdown: Breakdown + ) -> ast.SelectQuery | ast.SelectUnionQuery: + if not breakdown.enabled: + return events_query + + return parse_select( + """ + SELECT + SUM(total) AS total, + if(ifNull(greaterOrEquals(row_number, {breakdown_limit}), 0), {other_label}, toString(breakdown_value)) AS breakdown_value + FROM + ( + SELECT + total, + breakdown_value, + row_number() OVER (ORDER BY total DESC) as row_number + FROM {events_query} + ) + WHERE breakdown_value IS NOT NULL + GROUP BY breakdown_value + ORDER BY + breakdown_value = {other_label} ? 2 : breakdown_value = {nil} ? 1 : 0, + total DESC, + breakdown_value ASC + """, + placeholders={ + "events_query": events_query, + "other_label": ast.Constant( + value=None if self._get_breakdown_hide_others() else BREAKDOWN_OTHER_STRING_LABEL + ), + "nil": ast.Constant(value=BREAKDOWN_NULL_STRING_LABEL), + "breakdown_limit": ast.Constant(value=self._get_breakdown_limit() + 1), + }, + ) + def _get_date_subqueries(self) -> ast.Expr: return parse_expr( """ @@ -358,24 +402,30 @@ def _outer_select_query( groupArray(total), arrayWithConstant(length(date), reinterpretAsFloat64(0)) ) as total, - if(row_number >= {breakdown_limit}, {other}, breakdown_value) as breakdown_value + if(row_number >= {breakdown_limit}, {other_label}, toString(breakdown_value)) as breakdown_value FROM {outer_query} + WHERE breakdown_value IS NOT NULL GROUP BY breakdown_value ORDER BY - breakdown_value = {other} ? 2 : breakdown_value = {nil} ? 1 : 0, + breakdown_value = {other_label} ? 2 : breakdown_value = {nil} ? 1 : 0, arraySum(total) DESC, breakdown_value ASC """, { "outer_query": query, "breakdown_limit": ast.Constant(value=self._get_breakdown_limit()), - "other": ast.Constant(value=BREAKDOWN_OTHER_STRING_LABEL), + "other_label": ast.Constant( + value=None if self._get_breakdown_hide_others() else BREAKDOWN_OTHER_STRING_LABEL + ), "nil": ast.Constant(value=BREAKDOWN_NULL_STRING_LABEL), }, ) return query def _get_breakdown_limit(self) -> int: + if self._trends_display.display_type == ChartDisplayType.WORLD_MAP: + return 250 + return ( self.query.breakdownFilter and self.query.breakdownFilter.breakdown_limit ) or get_breakdown_limit_for_context(self.limit_context) diff --git a/posthog/session_recordings/queries/test/__snapshots__/test_session_recording_list_from_filters.ambr b/posthog/session_recordings/queries/test/__snapshots__/test_session_recording_list_from_filters.ambr index d5aceabdff1e3b..435f4a02949d1b 100644 --- a/posthog/session_recordings/queries/test/__snapshots__/test_session_recording_list_from_filters.ambr +++ b/posthog/session_recordings/queries/test/__snapshots__/test_session_recording_list_from_filters.ambr @@ -3371,7 +3371,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_event_filters @@ -3408,7 +3409,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_event_filters.1 @@ -3445,7 +3447,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_filters @@ -3483,7 +3486,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_filters.1 @@ -3521,7 +3525,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_mandatory_filters @@ -3566,7 +3571,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_mandatory_filters.1 @@ -3611,7 +3617,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_mandatory_filters.2 @@ -3648,7 +3655,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_mandatory_filters.3 @@ -3685,7 +3693,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_person_filters @@ -3734,7 +3743,8 @@ format_csv_allow_double_quotes=0, max_ast_elements=1000000, max_expanded_ast_elements=1000000, - max_query_size=524288 + max_query_size=524288, + max_bytes_before_external_group_by=0 ''' # --- # name: TestSessionRecordingsListFromFilters.test_operand_or_person_filters.1 From b0bd36b46e0b6a3fc93314deacc7ff336f1fb725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Fri, 7 Jun 2024 15:46:27 +0200 Subject: [PATCH 03/21] refactor: Update metrics to fetch counts at request time --- posthog/api/app_metrics.py | 1 + posthog/api/test/test_app_metrics.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/posthog/api/app_metrics.py b/posthog/api/app_metrics.py index 45f4f1a48c194c..b91cbcfeed5c2a 100644 --- a/posthog/api/app_metrics.py +++ b/posthog/api/app_metrics.py @@ -7,6 +7,7 @@ from rest_framework.decorators import action from posthog.api.routing import TeamAndOrgViewSetMixin +from posthog.batch_exports.models import fetch_batch_export_run_count from posthog.models import BatchExportRun from posthog.models.plugin import PluginConfig from posthog.queries.app_metrics.app_metrics import ( diff --git a/posthog/api/test/test_app_metrics.py b/posthog/api/test/test_app_metrics.py index 4fbe4f8bd7efc8..a6c154bea50626 100644 --- a/posthog/api/test/test_app_metrics.py +++ b/posthog/api/test/test_app_metrics.py @@ -149,6 +149,8 @@ def test_retrieve_batch_export_runs_app_metrics(self): data_interval_start=last_updated_at - dt.timedelta(hours=1), status=BatchExportRun.Status.COMPLETED, ) + for _ in range(3): + insert_event(team_id=self.team.pk, timestamp=last_updated_at - dt.timedelta(minutes=1)) BatchExportRun.objects.create( batch_export_id=batch_export_id, @@ -162,6 +164,9 @@ def test_retrieve_batch_export_runs_app_metrics(self): data_interval_start=last_updated_at - dt.timedelta(hours=3), status=BatchExportRun.Status.FAILED_RETRYABLE, ) + for _ in range(5): + timestamp = last_updated_at - dt.timedelta(hours=2, minutes=1) + insert_event(team_id=self.team.pk, timestamp=timestamp) response = self.client.get(f"/api/projects/@current/app_metrics/{batch_export_id}?date_from=-7d") self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -230,6 +235,7 @@ def test_retrieve_batch_export_runs_app_metrics_defaults_to_zero(self): data_interval_start=last_updated_at - dt.timedelta(hours=1), status=BatchExportRun.Status.COMPLETED, ) + insert_event(team_id=self.team.pk, timestamp=last_updated_at - dt.timedelta(minutes=1)) response = self.client.get(f"/api/projects/@current/app_metrics/{batch_export_id}?date_from=-7d") self.assertEqual(response.status_code, status.HTTP_200_OK) From c77a4fbdcb5f131c0ce2f46c387f58997856653f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Fri, 7 Jun 2024 16:07:07 +0200 Subject: [PATCH 04/21] fix: Move import to method --- posthog/api/app_metrics.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/posthog/api/app_metrics.py b/posthog/api/app_metrics.py index b91cbcfeed5c2a..c045e79026b358 100644 --- a/posthog/api/app_metrics.py +++ b/posthog/api/app_metrics.py @@ -7,7 +7,6 @@ from rest_framework.decorators import action from posthog.api.routing import TeamAndOrgViewSetMixin -from posthog.batch_exports.models import fetch_batch_export_run_count from posthog.models import BatchExportRun from posthog.models.plugin import PluginConfig from posthog.queries.app_metrics.app_metrics import ( @@ -85,6 +84,8 @@ def get_batch_export_runs_app_metrics_queryset(self, batch_export_id: str): Raises: ValueError: If provided 'batch_export_id' is not a valid UUID. """ + from posthog.batch_exports.models import fetch_batch_export_run_count + batch_export_uuid = uuid.UUID(batch_export_id) after = self.request.GET.get("date_from", "-30d") From b3333121e7919623f124221f711fff5e8c261d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Mon, 10 Jun 2024 14:45:12 +0200 Subject: [PATCH 05/21] fix: Add function --- posthog/api/app_metrics.py | 3 +-- posthog/batch_exports/models.py | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/posthog/api/app_metrics.py b/posthog/api/app_metrics.py index c045e79026b358..b1a40a80076ce4 100644 --- a/posthog/api/app_metrics.py +++ b/posthog/api/app_metrics.py @@ -23,6 +23,7 @@ AppMetricsRequestSerializer, ) from posthog.utils import relative_date_parse +from posthog.batch_exports.models import fetch_batch_export_run_count class AppMetricsViewSet(TeamAndOrgViewSetMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): @@ -84,8 +85,6 @@ def get_batch_export_runs_app_metrics_queryset(self, batch_export_id: str): Raises: ValueError: If provided 'batch_export_id' is not a valid UUID. """ - from posthog.batch_exports.models import fetch_batch_export_run_count - batch_export_uuid = uuid.UUID(batch_export_id) after = self.request.GET.get("date_from", "-30d") diff --git a/posthog/batch_exports/models.py b/posthog/batch_exports/models.py index adf2d1a602a241..ae590b371c6a4e 100644 --- a/posthog/batch_exports/models.py +++ b/posthog/batch_exports/models.py @@ -1,3 +1,4 @@ +import collections.abc import dataclasses import datetime as dt import enum @@ -116,6 +117,45 @@ class Status(models.TextChoices): ) +def fetch_batch_export_run_count( + *, + team_id: int, + data_interval_start: dt.datetime, + data_interval_end: dt.datetime, + exclude_events: collections.abc.Iterable[str] | None = None, + include_events: collections.abc.Iterable[str] | None = None, +) -> int: + """Fetch a list of batch export log entries from ClickHouse.""" + if exclude_events: + exclude_events_statement = f"AND event NOT IN ({','.join(exclude_events)})" + else: + exclude_events_statement = "" + + if include_events: + include_events_statement = f"AND event IN ({','.join(include_events)})" + else: + include_events_statement = "" + + data_interval_start_ch = data_interval_start.strftime("%Y-%m-%d %H:%M:%S") + data_interval_end_ch = data_interval_end.strftime("%Y-%m-%d %H:%M:%S") + + clickhouse_query = f""" + SELECT count(*) + FROM events + WHERE + team_id = {team_id} + AND timestamp >= toDateTime64('{data_interval_start_ch}', 6, 'UTC') + AND timestamp < toDateTime64('{data_interval_end_ch}', 6, 'UTC') + {exclude_events_statement} + {include_events_statement} + """ + + try: + return sync_execute(clickhouse_query)[0][0] # type: ignore + except Exception: + return 0 + + BATCH_EXPORT_INTERVALS = [ ("hour", "hour"), ("day", "day"), From f8141e08cc7ea73f824252d9f2017176dba1e7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Mon, 10 Jun 2024 14:54:54 +0200 Subject: [PATCH 06/21] fix: Typing fixes --- posthog/batch_exports/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posthog/batch_exports/models.py b/posthog/batch_exports/models.py index ae590b371c6a4e..a312ae21eeabd5 100644 --- a/posthog/batch_exports/models.py +++ b/posthog/batch_exports/models.py @@ -151,7 +151,7 @@ def fetch_batch_export_run_count( """ try: - return sync_execute(clickhouse_query)[0][0] # type: ignore + return sync_execute(clickhouse_query)[0][0] except Exception: return 0 From 2e6b1732f015fc4f0fbd121781a0f95741735b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 14:28:08 +0200 Subject: [PATCH 07/21] feat: Custom schemas for batch exports --- frontend/src/queries/schema.ts | 8 +- .../PipelineBatchExportConfiguration.tsx | 97 ++++++- .../pipelineBatchExportConfigurationLogic.tsx | 238 ++++++++++++++++++ 3 files changed, 340 insertions(+), 3 deletions(-) diff --git a/frontend/src/queries/schema.ts b/frontend/src/queries/schema.ts index 5705f08fad00f9..282625dbb8a5d9 100644 --- a/frontend/src/queries/schema.ts +++ b/frontend/src/queries/schema.ts @@ -1448,7 +1448,7 @@ export interface DatabaseSchemaField { } export interface DatabaseSchemaTableCommon { - type: 'posthog' | 'data_warehouse' | 'view' + type: 'posthog' | 'data_warehouse' | 'view' | 'batch_export' id: string name: string fields: Record @@ -1463,6 +1463,11 @@ export interface DatabaseSchemaPostHogTable extends DatabaseSchemaTableCommon { type: 'posthog' } +export interface DatabaseSchemaBatchExportTable extends DatabaseSchemaTableCommon { + type: 'batch_export' + query: HogQLQuery +} + export interface DatabaseSchemaDataWarehouseTable extends DatabaseSchemaTableCommon { type: 'data_warehouse' format: string @@ -1475,6 +1480,7 @@ export type DatabaseSchemaTable = | DatabaseSchemaPostHogTable | DatabaseSchemaDataWarehouseTable | DatabaseSchemaViewTable + | DatabaseSchemaBatchExportTable export interface DatabaseSchemaQueryResponse { tables: Record diff --git a/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx b/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx index 3ef4466e2a540d..42d7f9055e27d3 100644 --- a/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx +++ b/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx @@ -1,4 +1,4 @@ -import { LemonSwitch } from '@posthog/lemon-ui' +import { LemonSelect, LemonSwitch } from '@posthog/lemon-ui' import { useActions, useValues } from 'kea' import { Form } from 'kea-forms' import { NotFound } from 'lib/components/NotFound' @@ -7,9 +7,13 @@ import { LemonButton } from 'lib/lemon-ui/LemonButton' import { LemonField } from 'lib/lemon-ui/LemonField' import { LemonInput } from 'lib/lemon-ui/LemonInput' import { SpinnerOverlay } from 'lib/lemon-ui/Spinner' +import { useState } from 'react' import { BatchExportGeneralEditFields, BatchExportsEditFields } from 'scenes/batch_exports/BatchExportEditForm' import { BatchExportConfigurationForm } from 'scenes/batch_exports/batchExportEditLogic' +import { DatabaseTable } from 'scenes/data-management/database/DatabaseTable' +import { HogQLQueryEditor } from '~/queries/nodes/HogQLQuery/HogQLQueryEditor' +import { HogQLQuery, NodeKind } from '~/queries/schema' import { BATCH_EXPORT_SERVICE_NAMES, BatchExportService } from '~/types' import { pipelineBatchExportConfigurationLogic } from './pipelineBatchExportConfigurationLogic' @@ -22,13 +26,20 @@ export function PipelineBatchExportConfiguration({ service, id }: { service?: st const { isNew, configuration, + tables, savedConfiguration, isConfigurationSubmitting, + isEditingModel, batchExportConfigLoading, configurationChanged, batchExportConfig, + selectedModel, } = useValues(logic) - const { resetConfiguration, submitConfiguration } = useActions(logic) + const { resetConfiguration, submitConfiguration, setSelectedModel, setIsEditingModel, createOrUpdateCustomModel } = + useActions(logic) + + const [localQuery, setLocalQuery] = useState() + const [queryChanged, setQueryChanged] = useState(false) if (service && !BATCH_EXPORT_SERVICE_NAMES.includes(service)) { return @@ -105,6 +116,88 @@ export function PipelineBatchExportConfiguration({ service, id }: { service?: st > + + + ({ value: table.name, label: table.id }))} + value={selectedModel?.name} + onSelect={(newValue) => { + const found = tables.find((table) => table.name == newValue) + if (found) { + setSelectedModel(found) + } + }} + /> + + + {!isEditingModel && ( + <> + + + setIsEditingModel(true)}> + Edit + + + )} + + {isEditingModel && selectedModel && ( +
+ Update Model + { + if (queryInput) { + setLocalQuery({ + kind: NodeKind.HogQLQuery, + query: queryInput, + }) + + if (queryInput !== selectedModel.query.query) { + setQueryChanged(true) + } + } + }} + editorFooter={(hasErrors, error, isValidView) => ( +
+ { + if (localQuery) { + createOrUpdateCustomModel(selectedModel, localQuery) + setIsEditingModel(false) + } + }} + type="primary" + center + disabledReason={ + hasErrors + ? error ?? 'Query has errors' + : !isValidView + ? 'All fields must have an alias' + : !queryChanged + ? 'No changes to save' + : '' + } + data-attr="hogql-query-editor-save-as-view" + > + Save + + setIsEditingModel(false)}> + Cancel + +
+ )} + /> +
+ )}
([ props({} as PipelineBatchExportConfigurationLogicProps), @@ -51,6 +244,11 @@ export const pipelineBatchExportConfigurationLogic = kea) => ({ configuration }), + setSelectedModel: (model: DatabaseSchemaBatchExportTable) => ({ model }), + setIsEditingModel: (isEditingModel: boolean) => ({ isEditingModel }), + setModelQuery: (query: HogQLQuery) => ({ query }), + createOrUpdateCustomModel: (model: DatabaseSchemaBatchExportTable, query: HogQLQuery) => ({ model, query }), + appendTable: (table: DatabaseSchemaBatchExportTable) => ({ table }), }), loaders(({ props, values }) => ({ batchExportConfig: [ @@ -98,6 +296,27 @@ export const pipelineBatchExportConfigurationLogic = kea ({ + tables: [ + props.service ? [getEventTable(props.service), personsTable] : ([] as DatabaseSchemaBatchExportTable[]), + { + appendTable: (state, { table }) => { + state.push(table) + return state + }, + }, + ], + selectedModel: [ + props.service ? getEventTable(props.service) : null, + { + setSelectedModel: (_, { model }) => model, + }, + ], + isEditingModel: [ + false, + { + setIsEditingModel: (_, { isEditingModel }) => isEditingModel, + }, + ], configuration: [ props.service ? getDefaultConfiguration(props.service) : ({} as BatchExportConfigurationForm), { @@ -197,6 +416,25 @@ export const pipelineBatchExportConfigurationLogic = kea { + const customModelName = model.name + (model.name.includes('-custom') ? '' : '-custom') + const modelFound = values.tables.find((table) => table.name === customModelName) + + if (typeof modelFound === 'undefined') { + const customModel: DatabaseSchemaBatchExportTable = { + type: 'batch_export', + id: model.id + ' (Custom)', + name: model.name + '-custom', + query: query, + fields: {}, + } + actions.appendTable(customModel) + actions.setSelectedModel(customModel) + } else { + modelFound.query = query + actions.setSelectedModel(modelFound) + } + }, setConfigurationValue: async ({ name, value }) => { if (name[0] === 'json_config_file' && value) { try { From b486865c1c02262a404b18489e6ce9e779d750c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 15:36:08 +0200 Subject: [PATCH 08/21] feat: Add django api support for defining model --- posthog/batch_exports/http.py | 1 + posthog/batch_exports/models.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/posthog/batch_exports/http.py b/posthog/batch_exports/http.py index b86e240fa5eb5a..9977b3bc757295 100644 --- a/posthog/batch_exports/http.py +++ b/posthog/batch_exports/http.py @@ -199,6 +199,7 @@ class Meta: "id", "team_id", "name", + "model", "destination", "interval", "paused", diff --git a/posthog/batch_exports/models.py b/posthog/batch_exports/models.py index a312ae21eeabd5..0390a44cd1d2ad 100644 --- a/posthog/batch_exports/models.py +++ b/posthog/batch_exports/models.py @@ -172,6 +172,12 @@ class BatchExport(UUIDModel): a BatchExportRun. """ + class Model(models.TextChoices): + """Possible models that this BatchExport can export.""" + + EVENTS = ("events",) + PERSONS = ("persons",) + team: models.ForeignKey = models.ForeignKey("Team", on_delete=models.CASCADE, help_text="The team this belongs to.") name: models.TextField = models.TextField(help_text="A human-readable name for this BatchExport.") destination: models.ForeignKey = models.ForeignKey( @@ -218,6 +224,14 @@ class BatchExport(UUIDModel): help_text="A schema of custom fields to select when exporting data.", ) + model = models.CharField( + max_length=64, + null=False, + choices=Model.choices, + default=Model.EVENTS, + help_text="Which model this BatchExport is exporting.", + ) + @property def latest_runs(self): """Return the latest 10 runs for this batch export.""" From 92bad377abf854e9ec05d2bd7d2428e5858057a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 15:37:02 +0200 Subject: [PATCH 09/21] feat: Frontend support for model field --- frontend/src/lib/constants.tsx | 1 + frontend/src/queries/schema.ts | 5 +- .../batch_exports/BatchExportEditForm.tsx | 11 +- .../batch_exports/batchExportEditLogic.ts | 5 +- .../PipelineBatchExportConfiguration.tsx | 103 +++----------- .../pipelineBatchExportConfigurationLogic.tsx | 127 +++++------------- frontend/src/types.ts | 1 + 7 files changed, 77 insertions(+), 176 deletions(-) diff --git a/frontend/src/lib/constants.tsx b/frontend/src/lib/constants.tsx index 106c55e8a92ee0..24cafa051df9a5 100644 --- a/frontend/src/lib/constants.tsx +++ b/frontend/src/lib/constants.tsx @@ -155,6 +155,7 @@ export const FEATURE_FLAGS = { WEB_ANALYTICS: 'web-analytics', // owner @robbie-c #team-web-analytics WEB_ANALYTICS_SAMPLING: 'web-analytics-sampling', // owner @robbie-c #team-web-analytics HIGH_FREQUENCY_BATCH_EXPORTS: 'high-frequency-batch-exports', // owner: @tomasfarias + PERSON_BATCH_EXPORTS: 'person-batch-exports', // owner: @tomasfarias // owner: #team-replay, only to be enabled for PostHog team testing EXCEPTION_AUTOCAPTURE: 'exception-autocapture', DATA_WAREHOUSE: 'data-warehouse', // owner: @EDsCODE diff --git a/frontend/src/queries/schema.ts b/frontend/src/queries/schema.ts index 282625dbb8a5d9..3f0a96f09e288a 100644 --- a/frontend/src/queries/schema.ts +++ b/frontend/src/queries/schema.ts @@ -1465,7 +1465,6 @@ export interface DatabaseSchemaPostHogTable extends DatabaseSchemaTableCommon { export interface DatabaseSchemaBatchExportTable extends DatabaseSchemaTableCommon { type: 'batch_export' - query: HogQLQuery } export interface DatabaseSchemaDataWarehouseTable extends DatabaseSchemaTableCommon { @@ -1476,6 +1475,10 @@ export interface DatabaseSchemaDataWarehouseTable extends DatabaseSchemaTableCom source?: DatabaseSchemaSource } +export interface DatabaseSchemaBatchExportTable extends DatabaseSchemaTableCommon { + type: 'batch_export' +} + export type DatabaseSchemaTable = | DatabaseSchemaPostHogTable | DatabaseSchemaDataWarehouseTable diff --git a/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx b/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx index 4817d250b0cf27..12906569aea9fe 100644 --- a/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx +++ b/frontend/src/scenes/batch_exports/BatchExportEditForm.tsx @@ -107,7 +107,16 @@ export function BatchExportGeneralEditFields({ )} - + {featureFlags[FEATURE_FLAGS.PERSON_BATCH_EXPORTS] && ( + + + + )}
([ batchExportConfigForm: { defaults: { name: '', + model: 'events', } as BatchExportConfigurationForm, errors: (form) => batchExportFormFields(props.id === 'new', form), - submit: async ({ name, destination, interval, start_at, end_at, paused, ...config }) => { + submit: async ({ name, destination, interval, start_at, end_at, paused, model, ...config }) => { const destinationObject: BatchExportService = destination === 'Postgres' ? ({ @@ -194,6 +196,7 @@ export const batchExportsEditLogic = kea([ paused, name, interval, + model, start_at: start_at?.toISOString() ?? null, end_at: end_at?.toISOString() ?? null, destination: destinationObject, diff --git a/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx b/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx index 42d7f9055e27d3..71a19fd16fbf1a 100644 --- a/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx +++ b/frontend/src/scenes/pipeline/PipelineBatchExportConfiguration.tsx @@ -3,17 +3,16 @@ import { useActions, useValues } from 'kea' import { Form } from 'kea-forms' import { NotFound } from 'lib/components/NotFound' import { PageHeader } from 'lib/components/PageHeader' +import { FEATURE_FLAGS } from 'lib/constants' import { LemonButton } from 'lib/lemon-ui/LemonButton' import { LemonField } from 'lib/lemon-ui/LemonField' import { LemonInput } from 'lib/lemon-ui/LemonInput' import { SpinnerOverlay } from 'lib/lemon-ui/Spinner' -import { useState } from 'react' +import { featureFlagLogic } from 'lib/logic/featureFlagLogic' import { BatchExportGeneralEditFields, BatchExportsEditFields } from 'scenes/batch_exports/BatchExportEditForm' import { BatchExportConfigurationForm } from 'scenes/batch_exports/batchExportEditLogic' import { DatabaseTable } from 'scenes/data-management/database/DatabaseTable' -import { HogQLQueryEditor } from '~/queries/nodes/HogQLQuery/HogQLQueryEditor' -import { HogQLQuery, NodeKind } from '~/queries/schema' import { BATCH_EXPORT_SERVICE_NAMES, BatchExportService } from '~/types' import { pipelineBatchExportConfigurationLogic } from './pipelineBatchExportConfigurationLogic' @@ -29,17 +28,13 @@ export function PipelineBatchExportConfiguration({ service, id }: { service?: st tables, savedConfiguration, isConfigurationSubmitting, - isEditingModel, batchExportConfigLoading, configurationChanged, batchExportConfig, selectedModel, } = useValues(logic) - const { resetConfiguration, submitConfiguration, setSelectedModel, setIsEditingModel, createOrUpdateCustomModel } = - useActions(logic) - - const [localQuery, setLocalQuery] = useState() - const [queryChanged, setQueryChanged] = useState(false) + const { resetConfiguration, submitConfiguration, setSelectedModel } = useActions(logic) + const { featureFlags } = useValues(featureFlagLogic) if (service && !BATCH_EXPORT_SERVICE_NAMES.includes(service)) { return @@ -117,87 +112,29 @@ export function PipelineBatchExportConfiguration({ service, id }: { service?: st - - ({ value: table.name, label: table.id }))} - value={selectedModel?.name} - onSelect={(newValue) => { - const found = tables.find((table) => table.name == newValue) - if (found) { - setSelectedModel(found) - } - }} - /> - - - {!isEditingModel && ( + {featureFlags[FEATURE_FLAGS.PERSON_BATCH_EXPORTS] && ( <> + + ({ value: table.name, label: table.id }))} + value={selectedModel} + onSelect={(newValue) => { + setSelectedModel(newValue) + }} + /> + + - - setIsEditingModel(true)}> - Edit - )} - - {isEditingModel && selectedModel && ( -
- Update Model - { - if (queryInput) { - setLocalQuery({ - kind: NodeKind.HogQLQuery, - query: queryInput, - }) - - if (queryInput !== selectedModel.query.query) { - setQueryChanged(true) - } - } - }} - editorFooter={(hasErrors, error, isValidView) => ( -
- { - if (localQuery) { - createOrUpdateCustomModel(selectedModel, localQuery) - setIsEditingModel(false) - } - }} - type="primary" - center - disabledReason={ - hasErrors - ? error ?? 'Query has errors' - : !isValidView - ? 'All fields must have an alias' - : !queryChanged - ? 'No changes to save' - : '' - } - data-attr="hogql-query-editor-save-as-view" - > - Save - - setIsEditingModel(false)}> - Cancel - -
- )} - /> -
- )}
) => ({ configuration }), - setSelectedModel: (model: DatabaseSchemaBatchExportTable) => ({ model }), - setIsEditingModel: (isEditingModel: boolean) => ({ isEditingModel }), - setModelQuery: (query: HogQLQuery) => ({ query }), - createOrUpdateCustomModel: (model: DatabaseSchemaBatchExportTable, query: HogQLQuery) => ({ model, query }), - appendTable: (table: DatabaseSchemaBatchExportTable) => ({ table }), + setSelectedModel: (model: string) => ({ model }), }), loaders(({ props, values }) => ({ batchExportConfig: [ @@ -268,7 +214,8 @@ export const pipelineBatchExportConfigurationLogic = kea { - state.push(table) - return state + loadBatchExportConfigSuccess: (state, { batchExportConfig }) => { + if (!batchExportConfig) { + return state + } + + return [getEventTable(batchExportConfig.destination.type), personsTable] + }, + updateBatchExportConfigSuccess: (state, { batchExportConfig }) => { + if (!batchExportConfig) { + return state + } + + return [getEventTable(batchExportConfig.destination.type), personsTable] }, }, ], selectedModel: [ - props.service ? getEventTable(props.service) : null, + 'events', { setSelectedModel: (_, { model }) => model, - }, - ], - isEditingModel: [ - false, - { - setIsEditingModel: (_, { isEditingModel }) => isEditingModel, + loadBatchExportConfigSuccess: (state, { batchExportConfig }) => { + if (!batchExportConfig) { + return state + } + + return batchExportConfig.model + }, + updateBatchExportConfigSuccess: (state, { batchExportConfig }) => { + if (!batchExportConfig) { + return state + } + return batchExportConfig.model + }, }, ], configuration: [ @@ -324,6 +289,7 @@ export const pipelineBatchExportConfigurationLogic = kea { @@ -356,7 +322,7 @@ export const pipelineBatchExportConfigurationLogic = kea [s.service], (service): string[] => { - const generalRequiredFields = ['interval', 'name'] + const generalRequiredFields = ['interval', 'name', 'model'] if (service === 'Postgres') { return [ ...generalRequiredFields, @@ -416,25 +382,6 @@ export const pipelineBatchExportConfigurationLogic = kea { - const customModelName = model.name + (model.name.includes('-custom') ? '' : '-custom') - const modelFound = values.tables.find((table) => table.name === customModelName) - - if (typeof modelFound === 'undefined') { - const customModel: DatabaseSchemaBatchExportTable = { - type: 'batch_export', - id: model.id + ' (Custom)', - name: model.name + '-custom', - query: query, - fields: {}, - } - actions.appendTable(customModel) - actions.setSelectedModel(customModel) - } else { - modelFound.query = query - actions.setSelectedModel(modelFound) - } - }, setConfigurationValue: async ({ name, value }) => { if (name[0] === 'json_config_file' && value) { try { diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 677ec5522e0943..d1418d93ddd684 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -3973,6 +3973,7 @@ export type BatchExportConfiguration = { start_at: string | null end_at: string | null paused: boolean + model: string latest_runs?: BatchExportRun[] } From 7277553c25652702bf0bd31bed8d84909028957b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 15:40:55 +0200 Subject: [PATCH 10/21] fix: Clean-up --- frontend/src/queries/schema.ts | 4 ---- posthog/batch_exports/models.py | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/frontend/src/queries/schema.ts b/frontend/src/queries/schema.ts index 3f0a96f09e288a..f38f33267c18b6 100644 --- a/frontend/src/queries/schema.ts +++ b/frontend/src/queries/schema.ts @@ -1463,10 +1463,6 @@ export interface DatabaseSchemaPostHogTable extends DatabaseSchemaTableCommon { type: 'posthog' } -export interface DatabaseSchemaBatchExportTable extends DatabaseSchemaTableCommon { - type: 'batch_export' -} - export interface DatabaseSchemaDataWarehouseTable extends DatabaseSchemaTableCommon { type: 'data_warehouse' format: string diff --git a/posthog/batch_exports/models.py b/posthog/batch_exports/models.py index 0390a44cd1d2ad..d532874bc32177 100644 --- a/posthog/batch_exports/models.py +++ b/posthog/batch_exports/models.py @@ -175,8 +175,8 @@ class BatchExport(UUIDModel): class Model(models.TextChoices): """Possible models that this BatchExport can export.""" - EVENTS = ("events",) - PERSONS = ("persons",) + EVENTS = "events" + PERSONS = "persons" team: models.ForeignKey = models.ForeignKey("Team", on_delete=models.CASCADE, help_text="The team this belongs to.") name: models.TextField = models.TextField(help_text="A human-readable name for this BatchExport.") From 0dada6371bfe849aa77fe57c47a32e81c5e35dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 15:53:10 +0200 Subject: [PATCH 11/21] fix: Add model to story --- frontend/src/scenes/batch_exports/BatchExports.stories.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/scenes/batch_exports/BatchExports.stories.tsx b/frontend/src/scenes/batch_exports/BatchExports.stories.tsx index dbd6779cb208d6..cc6bae517e1fac 100644 --- a/frontend/src/scenes/batch_exports/BatchExports.stories.tsx +++ b/frontend/src/scenes/batch_exports/BatchExports.stories.tsx @@ -27,6 +27,7 @@ export default { 1: { id: '1', team_id: 1, + model: 'events', name: 'My S3 Exporter', destination: { type: 'S3', From 4283b5f93bdd464783970212656e83e58cdf29bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 15:53:48 +0200 Subject: [PATCH 12/21] fix: Add missing migration --- posthog/migrations/0426_batchexport_model.py | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 posthog/migrations/0426_batchexport_model.py diff --git a/posthog/migrations/0426_batchexport_model.py b/posthog/migrations/0426_batchexport_model.py new file mode 100644 index 00000000000000..68f8fd2c729161 --- /dev/null +++ b/posthog/migrations/0426_batchexport_model.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.11 on 2024-06-12 12:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("posthog", "0425_hogfunction"), + ] + + operations = [ + migrations.AddField( + model_name="batchexport", + name="model", + field=models.CharField( + choices=[("events", "Events"), ("persons", "Persons")], + default="events", + help_text="Which model this BatchExport is exporting.", + max_length=64, + ), + ), + ] From a779907620b375aad9b1b855ac84547208c7a277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Wed, 12 Jun 2024 16:43:48 +0200 Subject: [PATCH 13/21] fix: Make new field nullable --- posthog/batch_exports/models.py | 3 ++- posthog/migrations/0426_batchexport_model.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/posthog/batch_exports/models.py b/posthog/batch_exports/models.py index d532874bc32177..598b6cdbacee5f 100644 --- a/posthog/batch_exports/models.py +++ b/posthog/batch_exports/models.py @@ -226,7 +226,8 @@ class Model(models.TextChoices): model = models.CharField( max_length=64, - null=False, + null=True, + blank=True, choices=Model.choices, default=Model.EVENTS, help_text="Which model this BatchExport is exporting.", diff --git a/posthog/migrations/0426_batchexport_model.py b/posthog/migrations/0426_batchexport_model.py index 68f8fd2c729161..37cee94f5ab437 100644 --- a/posthog/migrations/0426_batchexport_model.py +++ b/posthog/migrations/0426_batchexport_model.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.11 on 2024-06-12 12:48 +# Generated by Django 4.2.11 on 2024-06-12 14:43 from django.db import migrations, models @@ -13,10 +13,12 @@ class Migration(migrations.Migration): model_name="batchexport", name="model", field=models.CharField( + blank=True, choices=[("events", "Events"), ("persons", "Persons")], default="events", help_text="Which model this BatchExport is exporting.", max_length=64, + null=True, ), ), ] From 1119d9c406b39b8b8ba85e0cdd0a3513ee0b583d Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:33:26 +0000 Subject: [PATCH 14/21] Update UI snapshots for `chromium` (1) --- ...funnel-historical-trends-insight--dark.png | Bin 14543 -> 12643 bytes ...unnel-historical-trends-insight--light.png | Bin 14301 -> 12357 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png index f427261f0c8010f06b2182d23f21ea35f32b3b67..a820c399ecbf23f0a477f1d6c54d82101a2b8272 100644 GIT binary patch literal 12643 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 F{{zP_KF9z7 diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--light.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--light.png index fa79b1b313e1daf2ac05ee5cadcd1a1f37c26b24..1276a2564f958e5581ebd905eed12aa2877600ef 100644 GIT binary patch literal 12357 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 I_@!U}6Vnj=vH$=8 literal 14301 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 rZu Date: Wed, 12 Jun 2024 15:44:03 +0000 Subject: [PATCH 15/21] Update UI snapshots for `chromium` (1) --- ...funnel-historical-trends-insight--dark.png | Bin 12643 -> 14543 bytes ...unnel-historical-trends-insight--light.png | Bin 12357 -> 14301 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png index a820c399ecbf23f0a477f1d6c54d82101a2b8272..f427261f0c8010f06b2182d23f21ea35f32b3b67 100644 GIT binary patch literal 14543 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 F{{zP_KF9z7 literal 12643 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 I_@!U}6Vnj=vH$=8 From b64ad219e71dcf951e6705284a5ea8ea57b64cd7 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:06:07 +0000 Subject: [PATCH 16/21] Update UI snapshots for `chromium` (1) --- ...funnel-historical-trends-insight--dark.png | Bin 14543 -> 12643 bytes ...unnel-historical-trends-insight--light.png | Bin 14301 -> 12357 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png index f427261f0c8010f06b2182d23f21ea35f32b3b67..a820c399ecbf23f0a477f1d6c54d82101a2b8272 100644 GIT binary patch literal 12643 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 F{{zP_KF9z7 diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--light.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--light.png index fa79b1b313e1daf2ac05ee5cadcd1a1f37c26b24..1276a2564f958e5581ebd905eed12aa2877600ef 100644 GIT binary patch literal 12357 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 I_@!U}6Vnj=vH$=8 literal 14301 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 rZu Date: Wed, 12 Jun 2024 16:17:55 +0000 Subject: [PATCH 17/21] Update UI snapshots for `chromium` (1) --- ...funnel-historical-trends-insight--dark.png | Bin 12643 -> 14543 bytes ...unnel-historical-trends-insight--light.png | Bin 12357 -> 14301 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png index a820c399ecbf23f0a477f1d6c54d82101a2b8272..f427261f0c8010f06b2182d23f21ea35f32b3b67 100644 GIT binary patch literal 14543 zcmeHuX;@R&)_>GiYb|nZZ>0)CTTxn3P!W(Z?X_wnlZrqA0Tm%4ga`pb2uZY7sn;PI z1Z39AAY)`oWC&3~kSUQdgoFfzBtSyK9Fjot-^cd>?3fv{OkJ5(B<*H ztNsQZKivsi4GurN_~-}d^1BDHPoU$+U;ImhGY*WkWZ0rpH}CPwLnIf3@qh7uKbbni zfxff9AG4pJzSWswUGjp)JG1I(tkfG(ydN`Added+b!cel`p^Mr&c9QOi+8zY96-#8 zyLuwZYG!Bdf3H_Lyw=W*3Pu!_m37T;>9s<#jArzq$GwlEP$+R{dU9BAVIgf-Sbv?@ z)d+0Lnln|Q;rZZ~tU_54cUM6oc+RZfVilTq!pkeeI-J(d^Ao`aD?>UubF7dl>!8)c zb|1jAvZ^Dv=ThiZ?W>-GB@~sH2a2vh_h1{me0&NK$zG)2T6e8`-g4WpR$>DE|G-o5 z?gt|I@hSA)ul3*01RHSuKalo+Q`OV!yaHVmH!&%*=MUW6j#Q^=%@fC`nkRX*&>JDj zWi0BBuw*g!z_Ec-@89hC*7CSAi!Js=SepqAuljqCuyho|BM&4r2b!F^f!gQwOGO?#i&JDD6#}+kPhX76I;DzAH)b?P_iP#mc&M zPoMiDb7;+Yr2tP75YX`+s` z@yBFQKPNCqd~oYIVH&-Qh8h~X8RWPV5#8HG7dPp*a(o4U9KI=|Nm<;8Dz_@{-h%Xl zVJCBNi?t0ai%;!^RlAvWW3wJc!ha@)b}t}VSt<9n9~Iv)TNl!P|NDiZLV~mH*TePL zjw!k@<;3GwQ^evRfipkFb5O#kkB8(=RblDF)_N=zKSUq;FpexgsJ-|o^l?FOhaYHl3BvQhU zSBVmTsy-rlr(1MuwsH)vldjXNo1&DSSaqr8R{9nv-7TtVx&u~z3{^t8N7s5+_OvOEn^@)6TN9pk;Nq#2*4(e2z0`aLENVwQaoUR;nbtMO zPf9u^z@OzCPxR_Ib`$xY7$gjtGYLNTwwcdBMz>QP#A-!fK~utpt3sVa#jbu# zIELM;XSm8BYuNVeyJr5S(LD&tK$)K?&ywxXB<~1PpDSOQ>Q{|i)i<2S`!-tdf<;!m z3bh-Z_oSFsg?6=n=@ZC!$&1&moCq7Pi*?qi7?|EJ(&@LNo8;|?a_vfNx_#`>r{w%c z)!`f)Dcu)-b*&zYUu(^cX!ILERrZrIaob>q^D$lBo60=tCch5R1PN_Ez=Y4ke_6W7kRT;A7a zr%$ICHu`5SN-aJk>Sk)kathOyGS==p`?A@du9s;Y9_Q{PGDlF#>QL$W&P#iNiP^nf z3ht@LQo+hBf?Mx&jJ#lr%kkP%NdGl!W$A3arHCO~Sh7zbeh(S$yw~zG+&)Ia;_J(+ z@ZKzYSvR2sM<*IuS&$m0?xYxN3bGwUOQYnr(9Ae@H#au{9vxqxPP`iU08v9QxF zJ?;%lcH1A?Ie1!`WLPC6YD^J<@o!)4a6jiaJn#f|@M7P%qur(Bl|Neto&btrZ6`Zs zH0i?+;AM@xPc4HIjnYXry!N59N!kfsAvQ2^M&!{TTS|`L*0_Y6#z;)k_SDA}ebJm_ zbnv^T>x@i`0Ow>k2dq1jNa!g+lKC+mW$BKp$0^3TKWGYOK*j+S<;SaQseKZI)AGy& zS#OqIKW=j3g^Dl8bz8`qbhN(ErZZo$THFF`bl@X@rS6E}LBa*+MCDCx)J-l>rVHwn>1x zyU*Ke&&sWr17-eR#PXstx02X_wgu8sKmvNWgq3h~o9dd3E_AkAsIEHc>6wfs&E3k1 zQWvF&AdOTtM)@`37xgO#{M;}Dwws-=KEx{{Cj<xFw(zYF)&}jZ z{JwpIQOt-|#oR#3s2T7pVQE@Tu&(Z!7W!=S@)Nq$!a>w7Jbh9^OiD6JJmW{pQmQk; zsX?QwN475feI(rq86q2u0#1YfITGKM?qn8DkMPAYMjo=jts7IfwmR)(J1NQY;}!iU znMhoR!M4`Hic#;0wJ9s=MRy3E6tV}*8Mn*lg1MWH8l^ra+c&WA8zO`xUTM9c4!3;c zO0BjfbFR~hoj>8{R;3EfESpza6vs*jCi+W|N65yWxVlIzL!rf%&<-+Awgqh9wFFYD5xr*hu2bqoYW36=C*~teV zQ%tQwJ73=fkwc$lSO2+AuvHybUc0Eiwbfc-oP^gOG!N4D7$lpn+ZOW!WvrX&nEHi> zy&c<8lei!LoG|?&Y0GkFRmvM%;_`2w5yjkw<@S=cbNgo1Qes*r`dPuO(Ap=cqWOWX z;6l^sm=_*Eui+tber>H(j-Pvem7GVT*@RPv_ZtMo1p3h z1Zh*@g1DpNfl@86l|Zqc{Oq~M{`o0v&*N5aZfsii{y6@#c|k(paeVkV&m}+y1u=}o zoqOi$M)QV-kdDn0ePPM%QV>J>*B>wQD@&FS*Y7dny}_Og2w*hFQO2%)W0@Z$#35ls zN(idzP|~6=nh|RSma{yi@GwQh2~lY=<8Pb|Bi?*7+CsQ%I>E2?w2yrHV}@;b4!O`3 zA#u;9m?oQfXqy#f)NR=DTmTD2MTL`C;`Fb2-b3ZE@SC!TE7g&fS2zF4pskR-e?GoV|N&mD^H+gZQSl3)@m+TP!2C zB*_mb8cC23lrlXtYcVC2tf6o-1Tmh)O}7sBj%)~{i|9F7_hFHpwPkvSbRX2cyB39E}uQb`?Sbi>^E(c81HfLBvcRfoi#q-eB+mEF^b z;_(wZ%Ip-&x(*jhCdE`G4JJ_?KN?ez;kC!~SJ{D8^+agXuM{S(bS^JcFwGEmoM)%A zNCI76Ks}ACoWo1X9-#{lCE?hnOWn2bt}c4#h6-lAx^7wZNbM968@rUY{xW%GY6fHj z=EL;K)JB5l{Onj8Zs{I#Y#1x_pHy30TjR#x!X?jw@A$nH8AcB73pywpX_qp!3yPFq zvsA0XbJ==N8jS5`S6s8}=3xipr>nL&E^$S2VI{40u+T zMBjP-XGp0L%$2yXq3SRwpfguiZhYzNj}C)^K^bjme^V0q37?I|Z8mBG`9kQ}>wCD_ zwjWc>U>t02s-&0yUU!~^gN)!IbUZ;ol0K8w_4~DzUhDAlc#xWjzunnw8Ij?yzTKH{ zGg1C~KnbN!+yVC(q7}PkSe#x=)~OVxzM@YasF3PCzsGoP$zwksNK9i0*) zylTO^kj8d?_8nAxU;A*aYrU<$PNNZXp&L`ZKo;_cWRfA5;H^~ZlNX%H-McJ zOmE6Pc>S=)PW!hmK>_bRA9=-IEu)DVy!S=D%R9F0LgC4unZsAw$UV=ZM(1T*25bE} z5ci5^=NuHDbu7(%(NiA4OL4rITW-A*W|4q-oevTq)~Ls4%gy0W41_IXZ6=~w^YUWl ztol|kuEVFr3^mtw~QkZVwLbOIudkE(DTr ztxp;?)eWe!*YEurv$EE6?GE4g&wG=49YRNMQ#)RBnD>=<8<(`hk=K}uV_RzTmD5IZ zFAHifCFQZd#q$0Bwu%%_s2tq0Gz$q4plJvCFp+cYcGQo9cv9cE5q=rr5`bKkaZ_?j zPAYS*Sl4VozZl3vjPi-C!&_`*jI5PhVf*3=-HkFo$=#k7wAdjdjTksb?Ycm45GsV=3=Gp9T1$ZuDFVdh@E%x@&rH_WtTA}C;md0r*4&NEddy<21Te*ha9 zmO4M%L2}o5!;9twPrlDS$!M!lvCOlriklK*Q_HNvjzmsaeOnmR{oSGK{fwG{P4(U) z&C$>zi-QUhW^7ZE_439}CCfn(I#iAG*ySvHb9GnuB`8aHxMtBsER>_bitH92Y{$sS z>^6=E+?=PVJ}QzmLr}+C+IbVTAxE$K5ux5|E9dSvbCJU|ty&sFb;42`NJ|DA5u+`) zlT{u{!f2PR`Mw#xNp`X`10T|KXB&n~C7r1KE#A%aeez%WcHm;2cMBPB;Xn&?Tph)!tU znKwyM2+DcQ6uo1+z92ah-LO+19*-8`J~KESA2n2i%EXZ7uR`Lt9lqpt2QD9R%{)Qd~eS*gwh8cW8-M6>kSW&Baa5S;(?QV@MAEyt;j+V>!|D=w&U1idH=}2%MigeW{y0_cm$NJeR4^uJiP?QhYAX2yyI; ziS-MXuY$On=RN)B%li6kSm8CyV|21d*P=A=F49>Y7=jxO!$ePkH8*o?yIu_^>+N(c z+AU>+L&r-6nE+3 z#fw%TU30XXE^^H{P+Q5G!t%30f)!er9rrT@%H~bm%IL%CW;uzw5GMni=qxN7>~*Gk zp#iz^R^Zs#LUhAS=%Ule8(E{KoLh>KoMLBZDg}l)X6rTRvY=$m0HR!Y&)w>%( zh{s26?+=?DI|Xvi=c=^5`a!HU$Gnq@-819-^LKMAM%QkEpZ!PEZAfUB?bY(-$Bwo{ z!J!{AtaDQKgy!DgjEZZ6JKH;1#$3qU{DtH&y*AvoD@`zbzyNEK24sgwu1fHx&B**~ zRN|C2QK6Z2O&d;szTFAiuP9=g5Dz-n%PX+rPSw~aztjP7j!j%4=euPtKrrL9idSL< z7_h{N-$r}$J2pe?7IB?XD*bxn@EIYue5&Dxx?`h}PrD&6GhKAy{zOVHvI~`Jhhn$A zLEb?yr~C`z?iEhho&>80K<0IkgoGcA=LRA>297Vju;--Yu)YR0Dyu4|6Kx_SXWf_lw~MYny;MBeT7w zyOo+&a_(KMV9UT|{5-V`7>1qtbyIJN4;j)3LwQ}Y=%6S+{VV^WupfqmeR>&M>(lEO ze}|2K{~S91w>e6^3lQs(#+-jueWCkYto}7sXIn;V)>B8~QSh@{y_5T$E`NMokC4xj zPEJlja34ENKwId#ydc^S6?jY2Zb=vV4j=L_ z4<_rPX@lqHmQ~%%a`~eJ-(f1n`^@e~#4g|YJp!<>Z3E9-E?Y8W?Xm{m<#}#s>+)N5 zCdE{vP^uzoyy*Q-)uIG|cp-d*1VFh2|D9et^j2-m#^U1Qey86^#b0uT)+^XCAxaLc znnVac4Lkj?pkQa(ikP0lAtay!RJBO5ymqqP#cE7d2=Q3rD;jy{4KpKpvrXJ^tb~tc zPvLN{t!gK(3kzM+_Uw-sH{W72pOQFb9#me+0r3#Rdyp}UZuEmX$|MI92SmSv3}3t?vJz^=TT)P{ z>a(plO=X9BiqeKxjag$np|&y;=ly2qJESB*(>5@F09n`EicamGv&7qu8|^ok9UCQ! zp_t}f=GV^^%(gU+V{<@8sS>d*+oe>;Tr1|xLI_LRVu*T>tCRieI5#hx8|q+-1oh~y zZ`PSi-;grYJyo@ma=3Wp>SEBOHfOm;_ZrK@c;^@{{}h;T_7W7PdmC_bUuM)_9~7#M zIQd;C4oykl)nOIhNC8vFPz>N04YmIFMo;8MP1Q+RwMx1FT>DM7_zo}9m2EtnW*-TZ z@MT5I+UL9DQeXXQ0;szk^pzR)XG^l2uz^xvF{`Z2dzjW)3%56WFNy{H;&_fQC>ED6 zKe!8EJ{REsW_jio0q-232#QzKSsyjQ#oNbR$OR-_0Z`9u6NbgY!B?UvV;)MU2d2Kr z?3$`6+RConVFEpXay}hd+=t`=9?Tw5*|yWL5NtyPWs1ftsJyLxkB1;`Y=1)MV1sR9 zbFtBY*Ex4!P90gNF9~$w@F1t}0d;etxTK`&Y^z@MyY;Q2o}iV8Yb}jWzPJP5xz41T z6x#V9y%rOms%A_L)w~bDhxG0CN~!cf@hP7|AGWdT)hh$>_~ScIN;!a5;>Su}E);`Q z1kirsG&u7+Gtv}1bx^+VsL8!#X2MB`Rf-+(b$}Rytd(K(PV>E3y$a@nUHQ%M*MtCm zmK|n)oa~vsVvjb#S5x^%YcOtfsLqGItS#>71$@YXaGG~rjLNmVadI}q*Z|01?H9b} z42T8M>M%2(Kz-bd$P^)LWX$!rP{%5mPB|#GA_M$UUa%cAO=DS+YIRYN8-OMI!+ORN z7cuMd6gCbaZyvsINn`_lJ5|qS{BAd(Yo9x>D`49=h(->P+hyD;%>0R?dEsenD76gj z8{dbZIK}a-5wq#+hYf}g)91dVofHirl5)JFk+`?XETX}UQjTxM@B6OBYCP0 z@wMB9;-tGNP6ZkToxO`7$a;|6BRPKsz?l@&S`nF!ls57tcbo38@J&baJSFZEZypgC zt&LAIGBRZKx<}jsoki_@r8!WB5Ewkf>_Pa-S!0~#yb{;BU@OQnwOhDP?F*oyc&?c? zP8u2ZXEmxGqm2=+K~MlIW9Um-S(qd$`L$ePp;P75V!h~9nmGGy+;gpFCxRg<|7MZy z+!|Zdns;R}HVVyj+U=mQc{r(lOm0m4hhNRblp0QCx+!k@5nKYq<4S=T=Gq0CLvOKHNknZ(T0}$lkuYI- z03{EwCMi?9KUqx%Uh|fbibxs5GMN^w#+dWj3LaL--T|Wi)8NSErv4PAp>+o52$p|V z^BF;t?Ku7XkZQ=squsb(k#Uo_cvDuPX@FBeR64%i{ALN8MrF>38}w;(9@ zmS*HCh#22enc7gW$!XJ_1SlCYFO+JiaguFV#ozp`oj z(a@4e|4>dqTs!ciX@DZVPgrz%#!60=;!kgWCY8fQAT1`nQ_5>Nas&mhi+Nukp^T+5 z>vpr9HRQg&-ODS3!Q=pga-|%Pptx8tzFoKN83|BZVR3@6R=)1}%kc!=8hzyK7@1;9 zc2;xdCx%O+Z9*ssT>*z=Xu=)oyR8X9J}o_qA&1GWvn@3vvW_GZ-zCM&P&oSa`c{+r zW5MeH^)R~n3?)YP>_@Pptv5u)aBNAjmeIw6>Gem~avZD|K;-7eZF0wKz?WGyymh zFiGsg0>88M{uFI0jkux?U0zy`pg73u%vujPeH-9hb(l86v6YtDqK6ApqvHnNK@b~w zuh`VOQi3LKf`^oTwoM&p96x<%wJ= z@+|Zw<^a%MIVc)kNdL>nhipr}KEz3>s3!P!k5)89mGKe;>c<9L_CA+dBfy!SIb0UC zY8se(YDsxxTzZFP{k*{hBbM5*^sYmt)n|9Td4!hSSJ`?8_4O5bR)LHxe{}7(T?*7e z-H)qoZUxZTK92u201hY?^9)z{5K!zsR*B88BZg`{7ghYr5JQ2eY&H>@S4|b>B-kSf zqt)|*I;2Ry`O2Dg`Mtn}1Fs)F%W*#@4k})JvChN-;07xL=E|yA zuRAQ684x*=Kqee^%{sVmn?vMXHyiGg*+8BRswVEzo5IPtGkaF0x5z# z;8OycApXleMCmc8dijqey3y}V3Q?IhfNr{`p^Ym*#prpvU$A1;v)%r&y#0vTmQ1u5 z@RjXqDK%}4J|BH!Aus_aSV>vrB7d*}>>-2{UCfM`%?S{ngNT0pk%axDa2=tYgchmL*=zAc1U^iY~;okx< zsjYBphFR{`185UxTLtk{NrG=M6dzt3HlQBAP^^!sob7CbliW8q|FN<-Y$l~L10h(l z(fO&o_dKuK7p@$};N?u^ofvsFB2qOvWv9WzOLqtT?GNv=r70FIhFDx!qDqAJjDzEC>e+>~lP}yR%+LNL}CYE<9#Ixc^ zFD1RPH8v`@rO_htg-9tar^}-`0S|#xO>|#TOzp-muT-hTnNY1e$Zn$f%OTK-@Vuuq z3JJ4dLs=t=K9L5PY2ZlWfAFim0MYaT=NQ7k1q~=XScGwCC}T~>RZs*x;;fBt|6IB< zOX=8u=6MbjQ;c!bg2egmR!}r^H#;6=?EiN3WDv7q ztWxH5hFTp~Mbyr|CZyY8yhYArAF#H=1NDx0#R|6?)w`4I7=sS&%u4s3v$WE^q7t(K zAxxddTB7CNu_WM{(;Ro|F{wB4qh0i#s-w!Rgjt_T7bBDp?>t z4^Yaur7QJT!QxKWYl>SR;X?ZT0nEt=WdPtPuDL?H$qri6Nkpmkyy4&`#05M&CKB ziEQ5(O=|pd3!ZR$n}bEr!P#egtnR7`6z2gz8Ew$2GgWdf{B;+d@9m4`KhuvMeA_Ap zfb%ZdS$ohe^FUh(m64-Zme|$4YcGM%IHZQ)Fr2?>{BuX^o_PcZ87Q+AL^xDHfI2o7 zK^@zx#Jgj~^$=Tk_Zv%5iCJzAClJ3K7}9&TF0tKqmvRGWA^FAEE8Av@Ht#UU@oc?g zcz*e}d|fxq9@R@l(}oM)D>pN;5g3;>q$U6i7`qYCYTL#Xz(vkY8jG1nJFn)Mp zD7$`_;V&Ra?I*O{^4i*5__mCGU0lNvz6LdR*LoTX$`=~o7h@usqjKPsi4Q=nlq&y5 z%iCubZj6DNO~PrQ+z~q27Y6piIX3KlpA0EhFKX=wlYi(3@Bl!p|62FWf9nVNS6g@f zgM&*Eha&Om=T~{4n+V@1$6tygbzaa^P7?nmhiz6K3D?m@`vaExUBy*A@H`r=u_c^M#I2Uu!D9-Zz$6U(?jW*83JI1lO+hAxqufdpHZvYApFc>i_Fh~-oslv15uxI5; zm0FuKr)t2zC#TMc6P?*KR8_fD?(1QCSo$^^f@C7rdagq%GvkN`tTO5$*q#aM825Fgrnr1RBWkKeII!P zy89dxUjRyRFxc7mA6LPC`}2#uzy0+k-d|tf{jc3zG$0z-Ot*6Ozn1~xu=`Kt|2XsO F{{zP_KF9z7 literal 12643 zcmeHuSy)qNyLQl4S_k;twpwJWW%`tvHHnA;EJaB)hzHw19jf>TM&IfZxICg5(NA1 zn+w+|qG{~?0N$TlAMigf{Cf6?$)!(!zp?-6!#790?zX@BFE9HwAG=ul5#v%Bvm4>% zZIky!)Os&uQE+8S&xA}zEF5xvow_i(!A}`^>hIhj%18d>ZL-7u>Bez+)D9p z+;So4?g5>)2}vE>3j)2rX#&y!?Kk@0p8TgN2auCZJ`;_|{H3M9nDO(Wdq7pcx3ugG zj}8oMEZUv-_aBPujc)=8hsz_$6@69ZFi}HH%#|xw=-=-JeO6vkacX2_Bu2eNLqajO z%sVEJ=h%C(#kbg{^wFaeLkMrSaJ>GtA?UOn@Jtu*+Ae-)!~TMazAHK|k4L`>YKj?h z2?z)%ut7!FAN&M#|$KV<7*$$xh1Edkmsk;;;i?0nSwOl z8wqdSDdHcw$@VK6tv*^XDyi;fM0VE3oNK%yRLI{}2w9DvSOjdQL2lqOp(_jDQ(G5H zL)Vv(M&?6sqHJU;wKqP4iTG2XzIj(y8c1*1nXtFFx3Fc`m0HK>VW-hpDsGEml3C(B zN(k;1zGI-6tG90E80W*U1`BdxOplCA5~mfHvlrZesQ)`=h-*|Ct`U%DJ^XpY;frG8HjfcjFPr;yu%42Q(RI2 zjI6?b7Z7s6B#0|j-d!#*GlaEbGW^c5Db99A5h>1`2)u_?yS!(ZW1UjCqqy21kRLtt z=S{M)uGSZn;QHvGQuM-GcfUgNcbHyam2V)lFudy}c3uW6X_eEs@| zu9*KefV3deA9<|5eU`=@+IXE2Is58PFC>#cTIMG{+mP_KO#0Pibk;PqhzjBKtbXu| z9$w(sU4Q#R$ecu=WW1m#`EQ@X$jfxrNm$)To<}{u5OOLjKk84}L_|HlYWn-8A)|!TEbbU4OU3`jNEVC5Y z>rG>qBvs8TE{j8D*pP;&JrL;(Yf5dJ&9P^adfDhQZ?IWf?go}ui|V`YLFc_XvU)ak zS%sLKW52(!If9a8c5~P(+3Bq5dn=Xw+Dx^N#V#LDn)B$_{Y8?w;`6}CCO=}U*%(%q zsgIh^=j&bEeRqs?52{@JwQX~BvVW(=V)E?gHJCKLhsbMM4 zxS*Hrvxyi%81Z#(FNE;nnsN8XB!-iJnQ!Pyt$jW{y!GXfo>U3!n9^$vMf(bfZE! zLE<}ySsrcdUfviZsfsf8ZS7%q+&~^#Y#Q#`51&z`nljcN-GV>C zc|Z8Nb}-7r!J$5Bn8TtNk3SRd!!1`g`v(N%c4)gg6~)z^Yr%*Lug%T$J-e7SzoV;~ zxf1Lu+E`4DF4G@+f)cnXg!K#obyu>zYF0ORLpdH(<`wP!z&`+#~857iRnYm{JalxBqMdVFmCQV@L z+jD*vN&lMbXgdG#d)>sl-2^H0fyHW2$9hG1L9VN~&3sqPN^IgLO!BDARVQ2Nl~H`- z>!TjFSKgcAX77~crA**r92bUKZRstH$*7y|?YbWis@DjLz&W(zNw&)yOSymE)Qm3C zP@rU7de3~fxJ|HTeP!WZzyEZFi?+Ly5JFJ34YkL-bm^yt7ik(C&tnVQB4ZI8{x6!x z6y+P=RN1}giJd#a?UVRR`zLFNCqn5^bM1EY&ru7|cbHaxFVwwS^ zge4PAxq_FP##1UO*p-3|I(7;nh72(kl+I%j$=zp<-7p^se_@9hy*%|CY?m-ql&&W# zfFLn04T*4^TVlxo6@t&^wb?|+84xyDi(FF2Yvuq@o}4lP9}0VP;DV<1gmL_2Q}>Hs zbXkI^jRIXSO}%GuchXyB2DJzQSiWv4wvtc9i`gdm;n``1MEmNH=AM*g`YsiY{ifIj z-E&6wP}c*SNOLgXK7idg>V34OwEpDshOnM(20N2MB-DET%oPLiQ84nvW2S(SQi^GH ziaaAf8H!=G3~mIN`Sy?8gtLi$8$Aspy4>Gu=U!B#s!-j>*gu$h7Z{!a+&^KZWlk)k z8D(7=t;H<9bM7?6Caa4sWuyKGYT<;Y2`swrLAKd#Xn`T^`nM*^2)(uQR&5L9wzW4D zq#kxACM|U_9sUDZ*vK(}kz18GY^KvX61Sb*NoHtljfN&7#yYYte48lW{#0jc)d;t= zh#=p(v_Vc+QOvE{pRIFm9g|vt{a<>8SL-i~fUPj&Nj!EL}Zfbxf+ z5R=p?3CJHjP8p4Y5lsMj$4Vs^uu!}aPAOg4!Agyb39K->;bk}bB!7sdx;-AfTy4A3 z53cWigZg#p^+|IQ+&V7e9C8(UdjxHe}t&s8zNu)67{&@#LR2Lf{tFoKoC-~DR{of%)jXB0SW_}S%%Z?*?p$B0AoLhgf*T)t5b)qgt zT|wh)jQz{J`|H{LpSG0JhujV*N17f=@x>bM`%U{63XdWq$Tmh=Y>XnBN3}@{D6Mw6 z7D6|Wr)Z_N1=01~T=dO+Yo;{XfUWJLjNG%PW{1hAZx4?IMCEGflZ~OyYrhQ-56{>2 z9wU`s@bBN1O#`XyjHkd>>dnm}$|b{ng}HmTxM0}&YDX6TnGur$6iGQBOX?CePu)`^ zg=1Q-P9(-^O#wtYFb!DGx7jK@={1l;y36FJ{MIu3!m z0OW9rBeCpli+75A(|6YZ;v$`v{>;;Q4{Tmt8x1Jp=hnA23>KUCCOR_tqj5UC@-kl@ zQ|U{|tK65_L(HNVBOOUb;kK&ypD~8#bH_IiIj@6Zg3LqRdlF5y(^ZNXa@Ez3qF1t+ zxNJw@BigoSe-FcrG~zZJv(;Iq2aV@UU-jp`=>?#;Kn&*Ql`xgOs#f2chWJTG(vAe4 zv{TON+eb(d+=bJ~#<-mV1ZrxH+lw^vv_u~~VBqZ}PlpH3f42J4Q)4&bYXNrT)t#JE zYx%}Oa6Ex1OQ$`F>dn*n`XRhz?{`_+q`LLZUTYQ^aQeqcj+OXYWjiad5EM4C`_=>& zA0Mwa;S;I{{JKt#87l{+yiUw114rrg7Ahkw;tQnHs-H`i58Fvw7`Ipm00l5aTO|9% z%{(dOpqV%2ft~7VLXH4F>KMD^Vu=jytsejxg3iWP>-x$r|ijx^HCle=-}aw~4%mcRewa*0L;eD0WPcc`z>!8{0# zQs9rzwLQZtGHjgZpBWuh7ujZ@p3syFQu&FM;?w| zqygt$>^OnVwnSSTpza~g4|X2K8NM*dK*BgS19sPDANO#kThRRyHtU{o%t(cc zzAL?MSgiQE`T_^E2jn9e_E&Y?%Vb^In9}th^%a>}^5x#vy*qVrJzP!SV zsE_XNIiYFzAcsi2#JtwGrqeRAm0OadyEXl#eo(=YP|3=n1?CG^zqVr?X>3L^a&si8 zSBo}7UzaOslV+BoP2T*O>0S8&>kF6GAJd8-{8AKm-vPhTHBQ#e6bn=hGPBAG1@>q{dNb{+z%qx1ogl;0+o7D3o-Y={jgw!E!XPQeg?0-Cf@%dMCKrA#ccy35N{rGu^E zYQmh0JzNfd*?-rtG?#z;H0a^t(vZvMAxlYIhj>UjU1FO&;xAcsg;sedI>%$ILZpp) zYf~=HCGfg8zsU?gFuvzjP*C0;%xk_$D}#r0o-6<0FshrDD$40}`fq^75#YNc%c>VO zg$ic9tk@pfkhWLY7Y_tg^=vP6<&yV3~=I-FC+2a!anl zl6Lh~T|;cQBDSa*yR@upn>7D)3ai>%U>~Dwg{mV^$00VkX(Be=xIFc@g@7PMl>2HYRqPcm72PQvtuF1 z>H+{}Lf}rby=qcs>O-YeR8$C^rJrqeMNK_izxXr+U(7VW{{)g!^#K*6@qVx4f#UDTVc5tyVg+E*r5#? zey_m6K{op#?Fm-AsrH=dt+B*AiJ{VnWRb1ey`U>o{f@^$@AnRUC4tUXm(qQfT9i(H z(A2B@wBu>FKVB(~2lkLSo|x*6=T0zCm4l1S7va?&;HN$GA``fK{fYQclj0UfMTvbY zMnn#*4*A^h2B0-LFRFY8bXYDX;jNhNEI+qLw(1})qhij~zk#E!ee^Go`>z1m&q3q+ zRrkw3JrdEseFsG}6wA6>k`tU&bKI5d?eQ~|h~lOI^!Q`8yjP`5K1ebt2zQ0<*W3{2 z2NbSunap+ibpZwA-Cg9y;3y!?r7B-2>Ics#)J%&Lp<95Yw?0bR-x3V3)X4in$YulTM#xtnBDQg&(TE-o4C=r2V)@ zb>?`HRHZmsrgRa&uMVa`^xRE>Qb$4b+&@|17@y*T5k5cz054G=>kW`C*G>cJv^M@q zZ*tc~c+bvqO+IOAvql^L@BSY5VA+^iDuwWc>dbdXp9C-ZYS7SIIN5NMYt;MFP<~B* z7}a>3(9DkRIJ8R~^9U_H=Gk_CQoQZCw6x?dd}MF_*EdSt0K$$i=COU+lD$J0s?MC9 z#HPAcCu=zQ0mO2^UFw(HxfeYCe0}qVQjw&@A)>Y;wdVnesk<5s&o|P7CTB;*)%TYr zNisO|s~7IOgo2dZbThWA3-enlb%#{9Xn~JN;GIut+=WB<`|NuqIIaJ!8sXC zj)2N8M(C_1Q&Uras;Cqg+ABz`ZJhdwfj%ZNq$y5D%~RwY@#|7A2f=dB$*AJg<*}Z+ z(UAI13L4;6J*Z{+P^C_D^3b^1R(Iz`n#IZ{YlmkYK&6!d>_|4K%`C#J2nZ^Pzcz(s zhdVDK%t|9WGc)p9WG%k z-ma`;&)_Z4OawL67#u;0+L}R1U(>}L<_=UggUw=>bgcB}WNG)RE9^v5d~4V)-FdY6 zn47y0o@b?H4rer{xB4bx)pjx<#G z{Nnf34H^$_DSHZ~JT=T(GPmybbtSsQPc*>7!wHVU)^B`w#_z}mnlr2WpbtqbIZuvy z2XGR#)V%ND0u8EItNK2o1etHeSlp>xm+h7MNmr)N``g*I<7;R%%Jpx3l{|KiF^MH> zGVVTAncNj!bcmiR#!My@8+*yU8c+5zRllT>jcME8v6Dp;Ca^jgzbG)z=5kjwj10hK zQ`nok`uUtQnIYNzE#C@{>^{CvNLuPv<<}5-T^mA1Ai!_xqq7{6UVTX8S8-J-j5o}O zY8eDCZo~tOuK*CyUo#Up^zbA_BdM3UD=ZiZ3bm{Uo&uB)nMkLMC(+dZv7iPZKMZAy zOfoV$5;d2xZyw8XhQN21R2FqpH=(4{%&lCbAts@Uh;bZfU%gl7M)CF=4N~k zCj2K9efecHn_3Jo=D3Zims$A@R=ur|JO_FP`1m~*h2-ma{4EqPtFL&5*7vc1R{u)0 z$NbWhLobe6hRi=GVFlvc3R}O z0G%JGHAxtGpMg%pVjyny&x`4818bf7#SWtjRGY}osIu^_z85~tJu|xo_tmu<_ z+o1)WY0zx&o4Y>bIF`r}M)o5nDbxle&+|hQ;6fMssPPU1qH#Tf&A3VegxmAs;nNHM z9=O*JE^>_@ux`@iE5AyunM{^WV}c)voBf12S-b892thFhz%Qa6WZl}sN8<<&S0w)pmk0$wd%mjKL zCL*QbIgh*l69%=Dj|+e>ux{Tt>)t2=s8bnbXBm(;o2+`4Onui>#(=I-VS$*j{>@c&E$B=Z5dvEmu)-)FTJFyVmqjhh2(mG@hDEa?sUxbu*jCZ36?{wGq1;#*R*zM0peZ4 z&aS1JoWaOkg;MCY-bM08qTCkE02Zr+VLIs{u%jTKv z?i?IWFaLh~&4X*X0-$@)+?5*cf=$?HNw+|32IMeE8l+8g&r&#xxj0&lY@*>~ z=SL@3e(><MyX&hD?;1i+z>-9pVE+3+&BszR4!iWGW)!e|-|mY` znFAKW27h99KwxlG?GPa96n+E1-QN#e^MK{T_;pA1Sb(wTBOCnkc)MnDCzeXI7)(-Z zu1jdjf5X;STE+Zd52y;El+8}w@m;qZQ=bt2GG@`u>=S%3MB3X9Ye=8hSmFVBJOm2dqs+aM#&(Xm%qS~r!)e|uT^2nn< zv1`+v^$+!5d~)DL)by{UtzcHasczzZwSoxU>4xdp%sxpatlVlmQ0Rh=4TKXKH-0L? z^B4|-h<`I50{O}tF#EjxfK|`QGAr5f`(;$3sgY;KfD0fmS<%K%dZZ;#jnm~n60LiQ z?|(^4l7q7bOm(%N%5OYZDK!BFIHeSTev-x-gMvOtz#5>GSzmLO$lrTH!)F`n2jo6l z&cZIYEpBH%gMtGR`21Xh-|^$e&jTRJF@E9#H8lQ_|L?H%zIt|)fW4A?2n@(1fQb>< zac6a_ib;^y;+D!0>tfZ^v#OB0&sLM!N7QIrR8}zJV<7AaVGV^ z?M?tU2g_1k{&uH#v&Cl|+h5D{8K)mWuAt+s`rB39;`M}<K&H3gf@XkQf|MJek;jB9s){+tViTwb8>0!RiL;U45`smV47Ye8MMuYp#RV z2lO6?fa|F#yYY5J`EPBjv%gPCU))5Eey~H)J%a~_LM%fXy2{IFwPBA2KilfYBWS6s zyO$#@giXs_nY$}?Xts7AZA6O;;OU&12lH71Shtm)sWcQ5cev{ za&KYm6W2Y@E&Lz~Z^y~xtAI+ZF^*(I-qFJ+)q;6?pR`P(B8!@)UBX+FyQfucmUhv7 zU9Do@;LA*IF%E;7SR7geT2?D(@$C% zXZ0d$GOAv616_xCI%%eT3a~E`%O6+Ye#ek3$ppn<1i!Da2Tc_etMWhQyP5$#k4Uw{ zxhAqs+C>j|cQW#I6Q)iUX4gMJ?gSrcL`<^aFV1tz&io($d>(v{o0_ zE_$oDwNDIKoV0=?4P?5;(bVE`W@uv9-2yv1^b#P74%@q2I@JHc2>a1$C|CB)ic$(G zu!%fV%6>piw_@50D0t;p63F)34(F}s;(0(pj@lBAtEEfX1eh6I5CMk@9F^*R(af&i zeI&j8L}L3UW}-Qf2EYm4%XF*m6L6=xB*8@>KI8{*K!X+NreZ>nxO{?2p*^5VSvj0h z?q3#=`BvTGcyuwH^}DhonpTx6%rS8l1+n_k9PR@^;zP_nhRHgDNqr8SnP*+8fR6AR z1wDY%agI$+*$OiU8Widr-KEsj4`jF};@-?$n0wP+z}CNhC4tFnQu{(VJ)uBA#h>81 ze&__m)}SCh9uTYRxXQG7HA=wF5Wv+Hl@cJA@LIW08CwObAB8_^8*|z0>^7i6)khC!mK~(FOLLer(e$c($RXWOb6sCSW;!To+m{rft02>!Y`UELtD8Ae76bybjeK*rj}q*Ut9hyh2<=SX?+I!OLpRdRs=M|8#VFSs*qvMZ)`-{FULOV~2n6ab_q#@~e6@C3!?H2u zgyB7is~t2omNMM>S9+v+Lyp|Yq5|%NSQ?H2ygy5HSj}2X_)dGavs*v?2z2A~|Me`( z|9S!cX}trB6HmNQ7W+Uqv`^Q6^nUx(BZZMRAdrOzO7A*q{}+GL=*ZtVh4Rl*f7d+E zKbHK*l7HWH*gxL%k2n3}P5;!(zir&~pM>&HLis15{C}2E%=K=d(VKvH5lbBefu4N_ zQ1|l6%FqwIs;i*U(E(rJ=6-E}+&rnI(|zOPMfRHqk|Lb!`r~T>5~BS^#RCq{*qSZ<0voi7kmHjXg{C> z*&#=(qC*qvXWGvJL;ef8Nw8-RgOoInh3~T zD@bLEhDoLbMZqx27$783Ac>5DFosOuvuW?TYu&%@J>U8My1HB|3CWvxzk5H=Z`yBe z|72^m>5J`O$jQlV!kjpIMow-GJpF8X-CB5f+tGI(9#&z`Sp6th+@?G#C$~!ubM%OP zM8*U&>Y=0eBbltdWxw*-jrRZe^2qfsr+-cJJrvUPFj@u&T(zC@2-XvlpA4~JiVei*&{ z{-NAD^tfh=96Ip#^PlZPFaL2$?sIsE`(=F`dij5QaG*=b#SMy-%r|!wpA;AG+q7wZ zZ>1mlg6~~ILv1em`*%IEY`pgI-P1Sa=gQs}39ZjvuneXMBl8OwUbXYad2Wmazpf|c zyA3v=gJfT`Vk-7ovz#;51h=(!YPUv?hX&oBEI%O^J=;p}Dh?D~o2{;e<@oIQKZY$Z7Zga-XE%W9E#p2m=mtAs{%*4`n zqyI!l*Rcy1?{6YUT-90^7aAJsM=zHcE1(&WTdEG59LOu4$_!<-8Ozt*x)rG)Mt_gn z+WW*NaQpT#I?iNVd1dnAdaeJhS^IBHxl3iXY`G(voAZP7(!#56lJ_cA+9YRC-N>b$ zH@!m>qYdWqwKJ=??=DJOS>|_5W`?!KTVw-?-$UH2yy*p(Eh|OyKKu2H(bWP@SDr8Jk8j#PFH~K8&HnCua`CeXCQUKN zvv;rRyYKx12cr8{U(&nq`k&vhOr%T0x|iPl-XwT=L!S3y_@2KYmBZd~;KI?!`LU$4 zc4qoLJv~~5B~_e)?Tw0*>6;Ve=6waqR@M`uv2r8--a_$oyhULlyTrF$qghe==ieB? zRI_%|*;C2d&V&R*)*;bkg-1CvjG@6U*^}ZLLbFh2r$ze+=S{*U9!e!5-tRXypG?{3 zmR4p*6}AQ+3>tiq5z_QSe@OFQqB>PF8LaEm@^Ir0gF>=hYriin=l88}g&}hl8k}3I z^B6|h&UEbp)y1P*W#=19Wo<9i9c+?oMJ+~t#GJ^kc8bpMSohPjTPeJW*PC}5d%dr_ zZp3|fQBX#T*{iRw&uBZ!Lm%prW#!Kdj>eYNo)D%@F zRq#5c`owXI95E-H&k}a$nLFT^kF65*Sq*ceUAmETAC<4vt@1C6_8#u@BHHvuDDRz| zX;if%*gH6I;EBh#a_;bbsm7s~7Y4EIb9}bNA~W10Rx<9vyQ|xFVsVN|RM*VBc81_J z_pu|@Akc*~Kc-D(4ZXR8mCV!gU{JDY-P)+dHmQi8jhp3q!^bMcf@W-kl5fu0Jlg_h zo*jO>YyPyP5Rd8ZX=b&r>wEWX$ZVbBUY7?m!;QY; zr5T)5$it52rj&mS@9pj7GQ-)e&phh|1s;<8V-;=$$8Y3JLdPELE${ozdF#!AQs?Rq z%$P-{(*E;@m*+-H9Gg>At&$}NWBN2~GakCvM&>?wqOnEOw&jTY&TcQEhisXyPW%1H zjZP|FHaFIzrR&=k@b#ei!t=!47?p_k*EL8^zQXxfnTYK>+L_yrmq}zFe9Z;-6Lat~ zDTc7gpl=u56>Fn{8@WGG(rykD)0S!Cn;o-2%M53wVu%{vL$7Z?C6U^{jaMc&h&IBc z?A{hTv>Eq-v?Zi@>D#15>D*wL(G!si8v zpN(WzCVBJCv9<&DJvos?OUI?G(2j^Q&hZ_A4~TZ=Mi{~JILYY`ws(qKaxh-RupJP7 zS(-0*$geXeTEt-65=w*F=4_dCksh%lMzqlCPpVC3i@AnIlDRH=gfOb{zB(@hYirPV z{)WDawKY!2NtqohAaUbXZ$6Q35Eue&<=b#qsXw5kbGxZ7<8Eol7MXCip zHf-=}qlQRyWKtJqrgW|KRw^+#vri4vwJw4^%NWU3RcK9SNA0?Ed@41!i)Wv#e^)7e zSwg~0Zl>BYmmU+tr7G*jJ(eBr$k!d;5nOY%&4gdmG`=v&;QeuD-${b$%sjp#wI>DwS_D?k_nw2b&)BGRP(6FOJC8hGTXt8ZSW~yRV(?(LbS{tRRYY1J%%;Rp z=5lp7OlqHXuaiKD~;=NL)BgAb=<65M<%+F&{@vCKPZ0NsMTz~ z-1%DD6rX)f%(8TzW4e*&NO%hd$+I_@n3mtYxpFG_t7lX54ZAS}=mCS(Yd2oHe_)?m z)lj_^c|yDHIAA+&IKfbG+b;UM;f4f%GD`<9Y`(i)e^13=i1p>mmj$Y_8P&@7ziimk z988rg+*LL@NL}tBk-caHcupnFl1gk zd(Uj4PurQCLldD@fSGrwbQ^RFXC_%Hn3d8bn}cg+8fsu!F@!E#lcJtAb&m7@cn@fe zuy&MLz4(Q98O)3Gv-3wdp~LOX?AOmblFtRD0;m`!nlFDmN%ajypu%U>(wEPSXp45A zdvWE1G4rPo7#oIw*0d5xi{Skx8W+wCb>g;Vro)-_e6w&q3&2(|G$q?)qx_#}b{I=^qJtMsF&NM5Qpi-I(P?KDD!CnZ=I*JsH<~;pMBb7LU>+ z_m+b4qGNtujGh@z)N}J3DAe9w>1*sdeI?(3{et$#EoZ8=q%=D(EPk9gkm$(DHpPXM z4_qz~FEv^Obv&mmj}@SD4q@SVsA`4%?Xk()Q9pfz_R084?YR9A8!$0sz%S1mO2aNW zbB5lxKB#K+iC6#n!_YfzSy5A|+T*L3)#2@|D8AeJ7=!}wEOTdA-?uosyMwTLaec8L zm{Qo{Yfc;SqxGg0TjnngVkM@rpkGm?dylC+-UPRi`%FJuPzb-IlOiNfuOIEU1!`ym7nU_a#29CzCU~yO-W~ciCCQB-lM%-X-b!ybi$K zbf-yJ%hJp+l2QSs9mj>8DU=6CZmcc3CV{1o7B+jd?M`teH#Fzjq&q(CN?_MAg77kV zeJr=-3G zz0+VVP3|b_*n+YP>GO;)d#l4PbS^mc}T z{(v_AUq_D1+in{?ghNUL zXXcr~#@{(8n09+P_xS9{t$!PT#&DipGFOzBrd`0Adsf;%7Nuku6urA!fBB70?ET?; zCP76FeUB{TwcTqDt(M>H%9*Upid`OUqPf!DqXLQYVHq(C{lb?DvA?M!@Fz=`$9b@x zEzZ7~Ne3=A*!MDETC^&@@;6<5rSF-iO`F^xw6)-!CEi2>)-)(&L*<$cTfIP-+7Tuw zqNz%mRD_-Du;Sg?5p;rH?4}z&#pXZy*~23n3|TIPVy>AT9kSU%JUszbK_m0b^;nA2 zpvEw~w#*XH+!@Q%~68CvvMC~t~F z)U+Xx-=C%d^JtJUF)?KACMK9u8d>yNxj%iMg{Z&%VD!@TAoz|{eSb#^kemi4D_TGU za@v78Q~6!V40*7uY_`orvpMVf6@X5AmTaDccT*ZJuAWK@Ebo6J$gGc7Xje-#C4kr( z0XY`U`Fg1L#ER3r#M!Fjl93rcxL;AZfA0E|F5cqXbBd}D${Qu7`X)7+pHcKoLhWMJ z${4Q6`Sa=f{2wl!C(_RaJU_N}v+~1S>lE(NaAJEX-EEOFVFkXIL!%%Ev3Aq;2e8sU z?|wgmn|Y&1R9EzfzUtGSmHDAQ-uKn7>-&NAL*{#&&~pr-*sa=e-NpH{ffoIM3gcL{e`%Z<%hS57B0TSDmd&_i~P};CgrTTXrqg+k!dt1 zQ)Yf1%Tm5S5Ez@5KkpQ?p#s{|2L_i^GJDTLy5xHG%{TmJ3i2;T!*_Mh02|SWnmiCC z)_`62p`JJd>wUEA@+!zWaGsjfT)^y ziHC;%+4OL`jH)lp!>vQ%OC2@;4c|W3)6a$y)*t5@-Y_ei;;FW-k(CTeL@d{gH@*rs zBAFPQ>>6XgUBk@7xpXdJeRJFAHQ$A9v7>dau`7Be0r!>*V-rl@g;n(du2(XPymm`L zH4BJOBSHqyO6xE2>)~>Ie1Hm1mdT6qzj= zS`vBdb7a*n zOeYjXM$}X#ygHHtEFOsJT|ASBZvhS6`NSrDZk(=z{5vu5RJOSp5=G$lGH>0wb!~D$ z-#TSqD_*vU*TitH=M~+KUuo6S5Z^2db3=<7OG1uYD`7CYtyC=RI955g$lyFrsD4sk zgToN==NYoSpGhbF)H9ur9>_5Glbn#>W_hN1KJo10YdX>1_X4HzmE~baZ=#I>&043{ zzEZ}d=2ul!UE{ONu)H>#iXdhPH`VuvW&CF3f@fQF+jH{s_t=@v99^rRGI+O0-_F|f z^Vdo%Ln<1yGS;(?bw9)2$8%+Bgo~rAwOvgQSZDv4uYGQrJ5)0}PRf8#p-+Z7^ znRtD*eECv%8C>LFsZ{BiyS$5etGods=-@3Zt&!gek{ z+~U~ChXy#@e0kPW;rG)huc;}1`jqCA9+<3l@6dN@$M2p944jNNDCZh4^j*}&OU2iw z292!1hR2&_g!ph0 z5G-=QEH;6CPY2gGRj)E|nHejZOg-p*a7Q1ns0pk3Q6^ zypq3cvrthcyC*Ja-6ie1&=d`Mr^06VRU zE4gW~CZ#lkDQK{XGP*nRBLGybj^_fCf|ym{ zJ;P|A0-c3w{KAqpl!0{?IFY)0dK}CbTZ3bD-Kwr(pqXcM>H)`Z*S2ozBUL2?Egn-mizM-!J|KBczM~e z#`4Nn4kHPS6h(Qtft`iqTAT5BVN0s6rcBD0Woh40wNk!%6m-{F@cx=v5#M=81u0HT z_nbUp^ud7#yMspc>d#FAE$&JYG5J1%5nAP3r}Zp2Ed!Jou|V|P-DzTg)|D^nD5vTyU1bj;n&yBD z?y@m-^Q=vpY)(^2>`53$@rHnZ73N7eq)2_yc@cIao@uyDD#d}r5_TlU+T&_LY-%*O zT^WGxTp=9@Ur@-2e4siF+TonDOw&S$fn}M61N2~`n(ydP9@Z`l_}}Cs(Jg?k$gxUP zQ8Eb&0K!R*;@27mGRj*w84msi23^Bsvh-}^!bGa}qWlc;WAs1}rSA9q(R+u2+1yXw&V;0?`ZVP(wqz=Nd=7`bV0$u~cpR8YmZFXXy)F>h zAe?9v2o%ogc>7qZl1PwWP=J+57I`-n-QQMF=8GIu5{_vW= zptt@ck_ae8u+22)Jc?Io+MrYOTYKz635LMO%S5=zGJ0A-1;m;}O}n<)c8hGt+{`h1 zs8Ow%)yaKqt};DoCoy?|zPKGSQ4O0kdz@Lw$XgAPtb!9T@g|JuW(!XN-({#9js5vJ1V%TK=3h+HZ8s&NU=atp zkEjltHa^}a2}jJEHKc(ZI$aQhk?^V zpujaSQy}rZDlG_x1D75nxv#}c;RcA*RD~yCCE~rDYaT-Wvla4T_zM00#0K5;1qdF> z%*zpeTEs^0tC@b)#EEW&rl3(fGxWv)PRJAFA#lb9;P`{k?A}$ipoHA|8QVaqL39GH zMI6tL0?Gx03C3Y=l40oJ;2>-Zrx4L$C>iyxZMYZ>eVFG#jeQFLetil80W=-nkIY1& z0fJBHo;?cmOXAE+Q-7lo#mRbVe88pu@0o762ipgtioqrR4A{0Y;{@Q6T}AU>zXw}} zf@u_Mz@CTB$Xu5lNjv?(#p4v|Jju7^;QPf&p6O;=gRhM8e@I593iG?bJy_m zs;l}^={{;UET~8PY1q3H+d!SFS>0=y{!s5!84czU#R9sZPQ`%kw76BPLm+eI{IX%+ zB{IU>6yYq-Q200iq8+UO(hSQkFC*k+n}tm55X%SokqxEp3uG~0o|H#L zr?3?;by2*bJ34I_6U`ijtFL~1_Xr0&5&{U49D;rYeEIzbjml$!O#iFItY-B7<_TH5>O3gHY2Y#=(GTor69%Jsv=73 zyHdYN7q+|rTWbZZ3?pm^J7y8eNl-zxV^#BZ2`um`tM`Otp!85HS!)4SuK*9pSN zB2^ZHmC<@Tw6tn{hZU@0e_FsCOa1ay`3f(aR;Qw#^u8Y!o=yYH3QU3o(ORLW)G{XvB zwqu6-Zy*`v9yM8Z3KZJSJQ{4M7{V(jl-sSqqB8arQM1$F)}Q)D`&xTmw3AjWhnL;? zjTDO0u=72wJ1+}5J7;C!M@%tb%PU5Nylgv5OUvS_v3&gjNMGxk#9eFZ0LJ!VLcs3i zIFa1@FBcS@adN776`9~`)d~Ye+0E8-0rxu|TalizP{aYI#|H#`KV%x6;Gj^95B)JW z6ayP%ig(bx0GeGu3r#n+kOx!uCoBdSkNjo{PPDA)xj{GsIJF<`*~hjw%Sia12cO@JA)HFn`vHk{Ta(ELz!dt zf%3rgRjb#I0C*H?2b(e=eO3{6WlJAG@Np0YTo9>eW|>8Ckz@hpV~v>G+>lqWrN&D3 zkeuf2yN>&lCpnLg4Y!YzsIi=lML;wwTPe71mIpUy{(xpd7>tdJatA1s&N6>`#?=NT zBf(oWr=L->iZ)Wv!T|`YO)@IbMjioH7wIy8(*^DrJfDL7FlAsTq^ks=pHV&{9JRxz z0bZ1o-C?^G3roi<$(9754K~o+E3$YclZ_tU;V-WBYxrM;K^HwI@k4tYoRDD0Fvv;ASajX03&rFj zg)Z3D(2baWUjw!o^r$W3ZIq-~dn}(Relhf~rn5(d?;jF-8#CbihsOa=0EdPmv3vH|eMub1umB02`xvZ_d z->rIva@h-LA5^X`#AWEUNs1hx_W#fgIsb`^`1fuF`gG?1$9tzfP1vUi`=7l#?^A_+ zs<2NL_Mg7z^;1`U>Z(s&^?!EN5`J>=m4|aoAHuRh4VXtE?7Lnx-zVy5hsV5|PH^ z<>7F+)WyY$G9UD_vR%O?l@ALF3i>C5cw8T0GZpW+DQ@LlJo1vlVf5_%?AI%|xa|5n rZuzy~ObP-rC01)`M4*a-fDn~Q#)!;A2(49X70@8_ z5UmVFNSJ3x5UL0vM418vh{_~mfRKbFB>DDnz2Cie-GA;M-(Bneadj=i!IPYv-~R3W z?B{v*x%0EV&CbtNKS!ZZJF!3ga2AEylmI`=pKXEv*~fI=?_02n&}DpSCxy6kbf>MxhX zn2(&a3U4kbNG(k64c&#YW!gtE^3Q(p^SRYc2akXL?H_+!56KwjV!R^mCG0qKP!f&S zRMzZSs1c5kYcR&`0fXZKcFbSdGtQe(#}4~*c}ghM^7vP9mp8xs@4oo;WvRK+CNx}o#}D! zrMcg(_Uo%PG2M>(xwOD`zG{;B++}%WlrIwSlUkIp zqhFyC&d+Z=NUV%niTNS{xl=B+-9q^jR6^t+jc~i4O>gMoxXhpe0|T$MZAG=lKC;WM zrCcxgCtK+g)VKFg|Ce48lpoI{g+= zK5ebKe_mJVGnD2rhn`aAL!ywSh#l$HbM3dba9=|urE?fiI@#ZCwL zp+wf$x<+z_;124O1m*HO#&waRKK`Bk<7aP&55Us+q=}WCXy_v!-OcqN?ah2g5u*C+R$XYQP#-uOfo-! zla8>@Iy;M~Rzl7qO}f;;qe)5HclR3FONEOij6Hf6?(Z}kJ%p`t=TGNr55;gcOy`(om1kh1mK&!qgq z!UJ&d>T{*2v2gZOaZz3uQU||m-a0)V%VQ#!&WRZDn;ow5B~9k1*q|`(&yEq?`PR%TvvTu{5}`q^R@VFxNFJUY)WHe%q_HfAs> z+9z)9=xqIEGbAI~N;DeE{51f=izRI=;)wx5@thugTvNV$``p3Q1-e4ciy|k-O==-| zMe=%*Xxeq&**$gJ?gL(2g2;Ul9X{K;U%J$U52nk6r*kb#91BllPn&V%H^yz!XJ7|y> zTOlmSpFfep-oN?=v;ItZFiK4(6|rm$TOM-d!a8$7zau+J%;|Wb?Mo&^n2ub1VxnOi z5G@za@Y}W=ruLX}H|8n2aXanGF=(vjrW*doFaV*@#{SFs_je4k@|HdAmV++||jrg!=86P{>c5MvGbU3WfE_A73#tFlF_4tHA^KzSZXS*^cC(k;zu%hCy^Tm*p z8c}b4>CUw@Yl#tb{r;ua^~nb|rkp|jx=~U#o@Q=HTfcHkSu@XpFy}ZNR5xbi*PA~Y zGfx?Kl7v)P53F}>Y0Oe5=USUY;jm(T3vmVU{_FQtt zNd?!Qsda6foYI(8tsZYTr=yL8knZ%(z_tkEo(ON zd~vUs=Dv_*x%Bdz+xvPKWJz=}6Tb?J)yC4`h#IL>?~(iIXoY9T+9Jn{AQielF6GqW z$)9fDa}I--M2XEpOow6r`76mpD`n^&r!;-T8R?ofTpEEbDR{3Z{SUYLYi})D9*1>3 z{0>VZ%h!q;)_QGIyy=JadC2!RNAs`4mrt(sIk4iTi|PAq)4b;Tivwi!j94hs>k65u z2uF`sv5Hz&9TUwKk?l!7x7Xb&9V~gxp(L+2t-t76KNSV@j9Vpv&)P=1an)ybDLjhe zCf?_X-*p@~;^x8c=DUO~1<$U_?i3GSnebt#&Wxqpn#Eu_Z`s;GO-^{?yE{6Si?y6- zjDnAG3okWnUOtXwa!%}010<|hyqr(gVc7p;)H~hX$iM$D|Ban0M%vtsX|t-SG`9nc zq;(USWk~x@Gi}B$6w)zb7i*j=7q~Z|tbE7>Veu`GWDV;|7Fz1np&og9e9sfZiR&V+%sM{>>D~7(&61n+Fx8!!gye#k=ee>QqRQ1Bw8k5BRK9W-w+QZ?=`rX z0k|9|tRgd4Iy4n|xucb}gC$xCJg=eh%b7<*t^_wsr3J#zfT$t}kX6?mT9k;D;(*R{ zsq%rEVdIF_4pu8a2>47>PN_=*;0xWwDj2}Zk4+te?E|LQRUa~eG~4D0ImJI4K{VK< z-YQ?#KG-Vk2OwZsi!S=~lw>>qk#ow_d#WY})h)ta zvT4Gaa8`*h+gKY_< z*1!8BPRij@zmfi%B6XqR4U}svOetBZ1+g_J%%1R z+F}`xh$E0ChVd(RbE4ke$+V0N4sM(++yU7E!LmD(^y#!mhf74Mm>k1X?%>AKln>N+Fk}Xm8bwyN0aAYVFmDfeRL^FSSDX zOtYCDOJ4W8=Xd)kZgu-&-an?SJ~xXME}YIf^4*OsJD+-_d534^wIkFF5ZWBDvhvv$ zHEl+&tf`UUnj0BPRzm+Ytv957J6C)qp7=VgxJ)zMieCmhLuUOM8e!YP*L?XWk*klL z!hN~kMkbAz`Zcv1a$~+*FD8za&E_YDC${QY_Ok!srxsZL{VkxjyX}vDvw7>T?i*aeYPC$dEWWWV5(?*YLnXQl)$t@5ouxetXR~voq8BPUrb}=#e^pggqv+MiFxb?_ z(pgdn7OC|@n`8~xuO(M>0FR1@BAj^pn*NbkVd;+dm{P%ypP)(yDRp+8?6RxzV|{2f zYqCOq=0xM@wJ3ji1g^^4gkTEm*2#|_iF9;X{<+G##u}YsdLljpklXnLrPGioX4KGx zK^;lzRX`heXjnz1;#uMjjQossMkr*YndRk)(yE>=W#W3fc4tW$EeqkeM1_I?i3qg` zrOzK`1*Y?pGx`^5Gt1Vx_tM<5C0bPM*z#i#H$FX`e^z1AYB{*Pti%Za+R~7vAioUL zn1bZcwrx6-(4_{N%D3WGj$Hj&;Ki6Pqoa53#LEUq&?KO5awVbRz#Fm9N%?%T!b-~~ zsoTzM>>-fs8Dx7%z%VpE1VDShc{0l*&E2hOq0+W;!Fm}$$xR@{DJ1NH!%MZCVDWn! zj4Pr0ftHO=+i%-4O#+uFf0$pqdD)BfY|X=?{v{NnsO2}nTK5q*RvM)Ei ze^Druyx~}0i^%8Y{cltbU-{wI4i%DbUi5s;0&qEBNG7B;9B|0XA&ADzFw$Wbl4ROg z(b8Cn;d4{>8$uxm&&q=qGH7F%Y`IjAG*ImI_m6M;{Qdiv$dyBZ1?VuwONi@lZzFpu zmayr0+L@+7t`WoD>1(rnI(4Jh85S5b-hmG)6jQ(UdV%Q53#@gy9mnHl;m`#W^M<~! zU9@_ahH&{2?^}Hs2g^>MmbG(FbCNyMvUWPl_E1+QI(%0rI|rVGc4!jg4CouHk={5& zN+L=Jm`>+z2dfA4jVVJUoFmZM5nX8hCSh|gko?hW?K@|IDQXbbUgt!PM`s?oe0-!P zAiadz_%!DAtfReoLE{)*wum2KBvFc!)Gen$;Sjd$+Lr-T3a&{krY$ssjsV*vd&?o5GN}>bXC=bd~evZ}Ity5g0q!!?L2)5iQ+7#Z)@Zo_az_fL|k9-lQv^2UcfldZF4 z15_4K&R0RlMIl@icxxe1As@!mWtA&06ph`?iVlrz(A5@^TtZ~!g4aF0?L!Xnt0~yZ zwy7~BexW_)I@qk--|NRBI8#V!Bb?_n8Ep;ntTRDrb0s%kYQjO3YF`b`Sn&S+Mv@vj`%jUCewK7ke}1n3H!E)09!g zLN|4lTzdE?jfS?46?P+?{fSL-PP}Ax7Bsm5)Si`a$P>v7L>W9jal7_XfPSB<&M!wd zAzp~)?9c^S6!wHPhu|F)EPWo~QXh5dpt53~q?5|tGsDCY_0?$@le;u&**c>#{e~K@ z-a06<-oo!fPO_CX{w6pN4WTpBOf#+?8ig=whC!2_je7XG>7HE90;_wlzu#-^{cDOU zk@Eb@W2kkMYxUJL8aY-^B;rB0aED|jH>NoJ?ca)1QZpRYphPX==iUbA%E`oYdkiAY z)3UPq!-mntVzzBVijG51Kv_%eNCyuJRxov*WF9&_nNHvEK46#i5Yj_w^OngB&!lK) zsvSqw2KDLJsMf8&&jT8kzxd>9)UnI|hnGvbjiT{beid1!hi_haA+`QT+F_k}&Cs^F zb=6-YxiS2@gr@NM!393>wZMw!d(1bM+l_%eRtIq+Qbq2#eX$D_nHXX`LWi`Hj=qy= z^jH`p7dXBxF7XI^jX(rW?>+hQ0Z(*o{r&~~rt;2PYQY)Mrl&weGVZAuUq{LbSRl)U zeGyEgpqgOtX^>1qNTt;Jp_8}$AZGeE%#29!3A=a`3rO;Y3q{*)a;m%-Ya{zI4gS9}UNdO8z%FJejnuFT13 zfH*~Nb-}Y-Ix!78oD&Bqx@cMOJXx^;J`PlKsGzneFXm|~c@ef~ zdb0hHj&AG*@~ttkDL1$8onEM7_1It}uOaWW+HdV-fXc{o#t~|Ug-&L|DNX*LcMZDk z=;UQU(po{ScuY0-WSQvV#9hut*WR?QEesoL{dn)CVuPh`@^XaN3QWQlM{0U&0@z&z=^m~v zi{cq_*?2tDgbjf|huv!yCX1a~i&KSO4k!#cR(#9gw1dCZ;Bujn^Y*PXPq! zf>JNup^1*W*@2K*Z`cdUI1NOO69zr?&=D?JU=+WxJ{L6cBC!PhqWp6ELHDKz3PPPd zX3^DN9M6s<%D5@0fl~!%i}!(*Fu;++>YL6MpF0SVqayce1TKqHG|jCoCnH69BByl0 zycrZ>Nu8Pb+uwFStrN@*lt@-)(4vMp3w;&oYH|Yzm2-^|i>_c(;k;pwbk(_#EC+!= z2Ab;FiRi+SfNZ7|pw+2y{P|v7bDO8KCb}8mTFsemfPBz=;-2x~)g@O?qT6aSjgaIT zisLQ;j+X!}t8esRQ{8oMY*h|^O)H({S2Tv$G3H1-m%cGf}z63sF8f$BasH$QI->|@Rp5{5QcsjWM9+a%f^A(Lf&GUgp~ zaXAZ{qL6VFcBFmb{bw@GLw%MYN7v@rhG4tA1n1bzN;owzI5-U+Xh0tHg18w=uFDjE z<=tJwLb&+`&_2fC7VHDEjV0L{G~^G*@TZx!MfSPZ;WnnAVtSA*)9zG`U%r9tC$rYg z**RS&FX}%)YcY0NF5K51C~HaU`LDFM)}hpt;myDW0rRg$B8EQ5Uf@TLq?-`XPG(eu zh3Lj%;=%rLnXSLM@`30x~uW21LA|1h*fH2G-^C{?%hFNh{gP2w{r|;2`Zw z+^#9Vzt6#5w6O?9Lv*c*k=IW& z;4DRtAH%2W=rVm!-{zC|Pmr{M`S@0jDtFqM4r>EycbpOx?B~c|+Mr45k)wxQgvo3u z%*v~;{{-ciKOBEL=jdT9BKJ!Lp-2$0DF>ziUd{-na?%dzOy}pD`ys})*D#|CP$nD@ zEKACxV-Op6IvYR!uELPF+^)=e^Xvw9B?O3vP`mT;ZS^#{Oj-m6He$mg0%8VGi%Mm$ z?b8HJ32Nxr+}zyL%V%*oGQ#GVwXxu;z8d?xxH6cdUUT z>M&^O*)&aH@@3S%`pf4B8IeOhdDfO7Nr$g9^!YapR5$~h~RA4SY;T8&-DZ6DU!6WfGKAm zwAf|YSil(vKNUd~aE>+)d!^Wsv~Bi<{D2TItChcZBZc7smaTRt*z`5M9j@bMw3S4? z3+0yz7#>k?Zz6$46s)`zzb*8NeHwA}e9+8|BRVB~aAc1_?p-N#Am<@2YG-9t890BF z2+avNB0PYn-(z((ufMyCC4m;Hj&TF<@9JMm~Ji&EZ#v=;CTdXRBT4pA;Hi5mr1_#04nNUL52 z-FO%&=ahVj(cfLwVI1i~mBWw88o8kO%O#tyfTV~94~ajS;^4&n%o@7VdHJp8W`-d> zE|rmFKAnM>w8P+hI5*`UnEpE_?q4%r;57{-&#=h!wp9?s2D=ZOeu?O35U|srwHWS^ zW2u_5_cp`e%JDlL;wztf;&!Xyn?rn9dAXU!zE1eqmFIgyK_L}VsZ@#W@xB-qMiCd@ zQkWi?od(&~{qIt*3s@us=~Ju~?u}uch@}oj)Ooy{d>-Z67bE&=d2R!2mY+z7YXT_T zgS-O_PrsW2#Aw$3P|5I#0>qzo4UsVxT7s}Ja$JmB9x zNROh&%PJve(;!l?*``5H@j0yP^lfG>z7t4=+SxG=c8v4})dg`(VTR=-jQ)+ze$ED`x>u+wPXd}cDQ8*C7BII}wv10mwydd)(gyTm5rJalY z!VCr|A4YT&GX(`%2A!+O2n}XYJ!x*inZVgiu?Q19$F_vN-P;l?YL-jpk>o`LlmE-S z@Ie=31gDA-{_ip4>9kCeY+bGJkZoMaVBJ|aw`?GIPIZxB+7&=C1=Kh!+e6f%2F^Qs z(`6^7zx*c(rOZd31rXXIUJW>3$mGvILcRI`X!J-b_yI`iB7OPM_cvCvxf_Lz&9ika z0CQ6awFKt=JHi`51N?|I>lAy7?_h8dP$lx)p>AduvUv>;hM`Rar+^GCIyhXuCjh;JdDbs%Pes;zDGVC7kdLWrkB z$fQtsp~#!_ z*3{DhECslUImjsC#O+;nAmIAwLdb^Z4=qv^fB3Y`3e3oa_Jh!^G)|4KzB zEeN=5Q473}jC-M{AU3dIs|<9DqxDy{BFocp(W{wxC6w6If*jVbh?WZ|Ugnlyu~v;+Cs_L=EPK4`$9#8CyJvvYIen?P|M_ zSM==0R$rh8ALevGWPD!#c@i0ev~>_GkeFEENezI=?q$2|C01|Ol|BNBc@!jDM!5eYvc;YTF={}2f?!gsZfj5O-G zyK*g_D4{N;rWsHif`Y~@@V>d5%i$4Gm(}Ta;ToTzP`toS(sMsf?Y~cXcI-r4(^5Vt zpD5ol{S0!Fy4i)9#p>gzh*Jl5W}4xJ7Rp;t38}FqH3#9@a1&%4;g|S*i*Td_9{RSO zNe+W)zj|+>9cOSz4|S{pzL-VYf4Az=v;XCp@;wPycnrKv&$apxo+kDITf;S=3WYlP z6t2(|vDjNNv1Rtv<+0=q6Tbn}C#XxZ8H@k!WAgv=IeRhP`K{+e@wLvIDENmxY5xQD I_@!U}6Vnj=vH$=8 From 77d80fd4f73170ec593e328bb6e46e23a6b6eb02 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:28:39 +0000 Subject: [PATCH 18/21] Update UI snapshots for `chromium` (1) --- ...funnel-historical-trends-insight--dark.png | Bin 14543 -> 12643 bytes ...unnel-historical-trends-insight--light.png | Bin 14301 -> 12357 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png index f427261f0c8010f06b2182d23f21ea35f32b3b67..a820c399ecbf23f0a477f1d6c54d82101a2b8272 100644 GIT binary patch literal 12643 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 F{{zP_KF9z7 diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--light.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--light.png index fa79b1b313e1daf2ac05ee5cadcd1a1f37c26b24..1276a2564f958e5581ebd905eed12aa2877600ef 100644 GIT binary patch literal 12357 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 I_@!U}6Vnj=vH$=8 literal 14301 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 rZu Date: Wed, 12 Jun 2024 16:39:17 +0000 Subject: [PATCH 19/21] Update UI snapshots for `chromium` (1) --- ...funnel-historical-trends-insight--dark.png | Bin 12643 -> 14543 bytes ...unnel-historical-trends-insight--light.png | Bin 12357 -> 14301 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png b/frontend/__snapshots__/exporter-exporter--funnel-historical-trends-insight--dark.png index a820c399ecbf23f0a477f1d6c54d82101a2b8272..f427261f0c8010f06b2182d23f21ea35f32b3b67 100644 GIT binary patch literal 14543 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 F{{zP_KF9z7 literal 12643 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 I_@!U}6Vnj=vH$=8 From 218b9fecba420d0608be9a6d903a985d01e020ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Tue, 18 Jun 2024 16:48:50 +0200 Subject: [PATCH 20/21] fix: Bump migration number --- latest_migrations.manifest | 2 +- .../{0426_batchexport_model.py => 0430_batchexport_model.py} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename posthog/migrations/{0426_batchexport_model.py => 0430_batchexport_model.py} (90%) diff --git a/latest_migrations.manifest b/latest_migrations.manifest index f48df9cd9a707f..0e208217e08533 100644 --- a/latest_migrations.manifest +++ b/latest_migrations.manifest @@ -5,7 +5,7 @@ contenttypes: 0002_remove_content_type_name ee: 0016_rolemembership_organization_member otp_static: 0002_throttling otp_totp: 0002_auto_20190420_0723 -posthog: 0429_alter_datawarehousetable_format +posthog: 0430_batchexport_model sessions: 0001_initial social_django: 0010_uid_db_index two_factor: 0007_auto_20201201_1019 diff --git a/posthog/migrations/0426_batchexport_model.py b/posthog/migrations/0430_batchexport_model.py similarity index 90% rename from posthog/migrations/0426_batchexport_model.py rename to posthog/migrations/0430_batchexport_model.py index 37cee94f5ab437..7f8722ade25ce6 100644 --- a/posthog/migrations/0426_batchexport_model.py +++ b/posthog/migrations/0430_batchexport_model.py @@ -5,7 +5,7 @@ class Migration(migrations.Migration): dependencies = [ - ("posthog", "0425_hogfunction"), + ("posthog", "0429_alter_datawarehousetable_format"), ] operations = [ From 4f182c7b2d8fc311cd6534a4379f0b0a3b635806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Far=C3=ADas=20Santana?= Date: Tue, 18 Jun 2024 17:12:00 +0200 Subject: [PATCH 21/21] fix: Clean-up unused code --- posthog/api/app_metrics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posthog/api/app_metrics.py b/posthog/api/app_metrics.py index b1a40a80076ce4..6fe56947b42c74 100644 --- a/posthog/api/app_metrics.py +++ b/posthog/api/app_metrics.py @@ -1,7 +1,8 @@ import datetime as dt import uuid from typing import Any -from django.db.models import Q, Count + +from django.db.models import Count, Q from django.db.models.functions import TruncDay from rest_framework import mixins, request, response, viewsets from rest_framework.decorators import action @@ -23,7 +24,6 @@ AppMetricsRequestSerializer, ) from posthog.utils import relative_date_parse -from posthog.batch_exports.models import fetch_batch_export_run_count class AppMetricsViewSet(TeamAndOrgViewSetMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):