Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(data-warehouse): data warehouse table breakdowns #20980

Merged
merged 48 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
7d609d9
create virtual table definition with the shape of events
EDsCODE Mar 12, 2024
45423e1
add conditionals
EDsCODE Mar 12, 2024
4de80a3
update schema
EDsCODE Mar 13, 2024
2d360bd
add distinct_id field
EDsCODE Mar 13, 2024
599686d
maths working
EDsCODE Mar 13, 2024
7f98927
add prop math selection
EDsCODE Mar 13, 2024
2902fca
merge master
EDsCODE Mar 13, 2024
95147dd
add field
EDsCODE Mar 13, 2024
4ee9218
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 13, 2024
57388ed
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 13, 2024
21b1ebf
typing
EDsCODE Mar 14, 2024
a367205
Merge branch 'dw-virtual-data-warehouse-table' of github.com:PostHog/…
EDsCODE Mar 14, 2024
5567f9a
clean up snapshot
EDsCODE Mar 14, 2024
01d93a0
cleanup
EDsCODE Mar 14, 2024
f8edad4
Merge branch 'master' into dw-virtual-data-warehouse-table
EDsCODE Mar 14, 2024
5c335d2
remove unnecessary
EDsCODE Mar 14, 2024
6f23254
more cleanup
EDsCODE Mar 14, 2024
4ccde43
add breakdown
EDsCODE Mar 14, 2024
1014956
format
EDsCODE Mar 14, 2024
e60f37d
typing
EDsCODE Mar 14, 2024
150ffa2
frontend selection
EDsCODE Mar 14, 2024
ac75ac5
returning
EDsCODE Mar 15, 2024
d29137c
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 18, 2024
e77c92a
add condition
EDsCODE Mar 18, 2024
06c8c83
typing
EDsCODE Mar 18, 2024
4f6690a
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 18, 2024
66c5bc4
add object storage test mixin
EDsCODE Mar 18, 2024
ccef0ff
remove client fixture
EDsCODE Mar 18, 2024
389d5cf
restore main
EDsCODE Mar 19, 2024
3b1c1fb
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 19, 2024
df4be72
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 19, 2024
4b92898
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 19, 2024
e202daa
add disabled state
EDsCODE Mar 19, 2024
c1b71f7
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 19, 2024
c309f16
Merge branch 'dw-virtual-data-warehouse-table-breakdowns' of github.c…
EDsCODE Mar 19, 2024
d6c1d16
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 19, 2024
a90f092
Update query snapshots
github-actions[bot] Mar 19, 2024
3eb257b
Update query snapshots
github-actions[bot] Mar 19, 2024
74caae8
Update query snapshots
github-actions[bot] Mar 19, 2024
95d3419
Update UI snapshots for `chromium` (1)
github-actions[bot] Mar 19, 2024
659a1d5
Update query snapshots
github-actions[bot] Mar 19, 2024
494184a
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 19, 2024
995f345
Update UI snapshots for `chromium` (1)
github-actions[bot] Mar 19, 2024
49ff76d
Update query snapshots
github-actions[bot] Mar 19, 2024
72d7cfa
Update query snapshots
github-actions[bot] Mar 19, 2024
cc74e1b
Update query snapshots
github-actions[bot] Mar 19, 2024
c6ee219
Merge branch 'master' into dw-virtual-data-warehouse-table-breakdowns
EDsCODE Mar 19, 2024
458eddf
merge master
EDsCODE Mar 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions frontend/src/queries/nodes/InsightViz/Breakdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic'
import { EditorFilterProps } from '~/types'

export function Breakdown({ insightProps }: EditorFilterProps): JSX.Element {
const { breakdownFilter, display, isTrends, isDataWarehouseSeries } = useValues(insightVizDataLogic(insightProps))
const { breakdownFilter, display, isTrends, isSingleSeries, isDataWarehouseSeries } = useValues(
insightVizDataLogic(insightProps)
)
const { updateBreakdownFilter, updateDisplay } = useActions(insightVizDataLogic(insightProps))

return (
Expand All @@ -14,9 +16,13 @@ export function Breakdown({ insightProps }: EditorFilterProps): JSX.Element {
breakdownFilter={breakdownFilter}
display={display}
isTrends={isTrends}
isDataWarehouseSeries={isDataWarehouseSeries}
updateBreakdownFilter={updateBreakdownFilter}
updateDisplay={updateDisplay}
disabledReason={
!isSingleSeries && isDataWarehouseSeries
? 'Breakdowns are not allowed for multiple series types'
: undefined
}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export function PropertyGroupFilters({
} = useActions(propertyGroupFilterLogic(logicProps))

const showHeader = propertyGroupFilter.type && propertyGroupFilter.values.length > 1
const disabledReason = isDataWarehouseSeries ? 'Cannot add filter groups to data warehouse series' : undefined
const disabledReason = isDataWarehouseSeries
? 'Cannot add filter groups to data warehouse series. Use individual series filters'
: undefined
return (
<div className="space-y-2 PropertyGroupFilters">
{propertyGroupFilter.values && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { taxonomicBreakdownFilterLogic } from './taxonomicBreakdownFilterLogic'
import { TaxonomicBreakdownPopover } from './TaxonomicBreakdownPopover'

interface TaxonomicBreakdownButtonProps {
isDataWarehouseSeries?: boolean
disabledReason?: string
}

export function TaxonomicBreakdownButton({ isDataWarehouseSeries }: TaxonomicBreakdownButtonProps): JSX.Element {
export function TaxonomicBreakdownButton({ disabledReason }: TaxonomicBreakdownButtonProps): JSX.Element {
const [open, setOpen] = useState(false)

const { taxonomicBreakdownType } = useValues(taxonomicBreakdownFilterLogic)
Expand All @@ -24,9 +24,7 @@ export function TaxonomicBreakdownButton({ isDataWarehouseSeries }: TaxonomicBre
data-attr="add-breakdown-button"
onClick={() => setOpen(!open)}
sideIcon={null}
disabledReason={
isDataWarehouseSeries ? 'Breakdowns are not available for data warehouse series' : undefined
}
disabledReason={disabledReason}
>
{taxonomicBreakdownType === TaxonomicFilterGroupType.CohortsWithAllUsers
? 'Add cohort'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface TaxonomicBreakdownFilterProps {
breakdownFilter?: BreakdownFilter | null
display?: ChartDisplayType | null
isTrends: boolean
isDataWarehouseSeries: boolean
disabledReason?: string
updateBreakdownFilter: (breakdownFilter: BreakdownFilter) => void
updateDisplay: (display: ChartDisplayType | undefined) => void
}
Expand All @@ -22,7 +22,7 @@ export function TaxonomicBreakdownFilter({
breakdownFilter,
display,
isTrends,
isDataWarehouseSeries,
disabledReason,
updateBreakdownFilter,
updateDisplay,
}: TaxonomicBreakdownFilterProps): JSX.Element {
Expand All @@ -49,7 +49,7 @@ export function TaxonomicBreakdownFilter({
<BindLogic logic={taxonomicBreakdownFilterLogic} props={logicProps}>
<div className="flex flex-wrap gap-2 items-center">
{tags}
{!hasNonCohortBreakdown && <TaxonomicBreakdownButton isDataWarehouseSeries={isDataWarehouseSeries} />}
{!hasNonCohortBreakdown && <TaxonomicBreakdownButton disabledReason={disabledReason} />}
</div>
</BindLogic>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const TaxonomicBreakdownPopover = ({ open, setOpen, children }: Taxonomic
const { groupsTaxonomicTypes } = useValues(groupsModel)
const { taxonomicBreakdownType, includeSessions } = useValues(taxonomicBreakdownFilterLogic)

const { breakdownFilter } = useValues(taxonomicBreakdownFilterLogic)
const { breakdownFilter, currentDataWarehouseSchemaColumns } = useValues(taxonomicBreakdownFilterLogic)
const { addBreakdown } = useActions(taxonomicBreakdownFilterLogic)

const taxonomicGroupTypes = [
Expand All @@ -30,6 +30,7 @@ export const TaxonomicBreakdownPopover = ({ open, setOpen, children }: Taxonomic
TaxonomicFilterGroupType.CohortsWithAllUsers,
...(includeSessions ? [TaxonomicFilterGroupType.Sessions] : []),
TaxonomicFilterGroupType.HogQLExpression,
TaxonomicFilterGroupType.DataWarehouseProperties,
]

return (
Expand All @@ -46,6 +47,7 @@ export const TaxonomicBreakdownPopover = ({ open, setOpen, children }: Taxonomic
}}
eventNames={allEventNames}
taxonomicGroupTypes={taxonomicGroupTypes}
schemaColumns={currentDataWarehouseSchemaColumns}
/>
}
visible={open}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
TaxonomicFilterGroupType,
TaxonomicFilterValue,
} from 'lib/components/TaxonomicFilter/types'
import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic'
import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils'

import { propertyDefinitionsModel } from '~/models/propertyDefinitionsModel'
Expand All @@ -35,7 +36,14 @@ export const taxonomicBreakdownFilterLogic = kea<taxonomicBreakdownFilterLogicTy
// This is a hack to get `TaxonomicFilterGroupType` imported in `taxonomicBreakdownFilterLogicType.ts`
__ignore: null as TaxonomicFilterGroupType | null,
}),
connect(() => ({ values: [propertyDefinitionsModel, ['getPropertyDefinition']] })),
connect((props: TaxonomicBreakdownFilterLogicProps) => ({
values: [
insightVizDataLogic(props.insightProps),
['currentDataWarehouseSchemaColumns'],
propertyDefinitionsModel,
['getPropertyDefinition'],
],
})),
actions({
addBreakdown: (breakdown: TaxonomicFilterValue, taxonomicGroup: TaxonomicFilterGroup) => ({
breakdown,
Expand Down
33 changes: 33 additions & 0 deletions frontend/src/scenes/insights/insightVizDataLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { dayjs } from 'lib/dayjs'
import { dateMapping } from 'lib/utils'
import posthog from 'posthog-js'
import { dataWarehouseSceneLogic } from 'scenes/data-warehouse/external/dataWarehouseSceneLogic'
import { insightDataLogic, queryFromKind } from 'scenes/insights/insightDataLogic'
import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils'
import { sceneLogic } from 'scenes/sceneLogic'
Expand All @@ -32,6 +33,8 @@ import {
} from '~/queries/nodes/InsightViz/utils'
import {
BreakdownFilter,
DatabaseSchemaQueryResponseField,
DataWarehouseNode,
DateRange,
FunnelExclusionSteps,
FunnelsQuery,
Expand Down Expand Up @@ -79,6 +82,8 @@ export const insightVizDataLogic = kea<insightVizDataLogicType>([
['query', 'insightQuery', 'insightData', 'insightDataLoading', 'insightDataError'],
filterTestAccountsDefaultsLogic,
['filterTestAccountsDefault'],
dataWarehouseSceneLogic,
['externalTablesMap'],
],
actions: [
insightLogic,
Expand Down Expand Up @@ -214,6 +219,12 @@ export const insightVizDataLogic = kea<insightVizDataLogicType>([
return ((isTrends && !!formula) || (series || []).length <= 1) && !breakdownFilter?.breakdown
},
],
isBreakdownSeries: [
(s) => [s.breakdownFilter],
(breakdownFilter): boolean => {
return !!breakdownFilter?.breakdown
},
],

isDataWarehouseSeries: [
(s) => [s.isTrends, s.series],
Expand All @@ -222,6 +233,28 @@ export const insightVizDataLogic = kea<insightVizDataLogicType>([
},
],

currentDataWarehouseSchemaColumns: [
(s) => [s.series, s.isSingleSeries, s.isDataWarehouseSeries, s.isBreakdownSeries, s.externalTablesMap],
(
series,
isSingleSeries,
isDataWarehouseSeries,
isBreakdownSeries,
externalTablesMap
): DatabaseSchemaQueryResponseField[] => {
if (
!series ||
series.length === 0 ||
(!isSingleSeries && !isBreakdownSeries) ||
!isDataWarehouseSeries
) {
return []
}

return externalTablesMap[(series[0] as DataWarehouseNode).table_name].columns
},
],

valueOnSeries: [
(s) => [s.isTrends, s.isStickiness, s.isLifecycle, s.insightFilter],
(isTrends, isStickiness, isLifecycle, insightFilter): boolean => {
Expand Down
42 changes: 32 additions & 10 deletions posthog/hogql_queries/insights/trends/trends_query_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
HogQLQueryModifiers,
DataWarehouseEventsModifier,
)
from posthog.warehouse.models import DataWarehouseTable
from posthog.utils import format_label_date


Expand Down Expand Up @@ -696,18 +697,39 @@ def _is_breakdown_field_boolean(self):
):
return False

if self.query.breakdownFilter.breakdown_type == "person":
property_type = PropertyDefinition.Type.PERSON
elif self.query.breakdownFilter.breakdown_type == "group":
property_type = PropertyDefinition.Type.GROUP
if (
isinstance(self.query.series[0], DataWarehouseNode)
and self.query.breakdownFilter.breakdown_type == "data_warehouse"
):
series = self.query.series[0] # only one series when data warehouse is active
table_model = (
DataWarehouseTable.objects.filter(name=series.table_name, team=self.team).exclude(deleted=True).first()
)

if not table_model:
raise ValueError(f"Table {series.table_name} not found")

field_type = dict(table_model.columns)[self.query.breakdownFilter.breakdown]

if field_type.startswith("Nullable("):
field_type = field_type.replace("Nullable(", "")[:-1]

if field_type == "Bool":
return True

else:
property_type = PropertyDefinition.Type.EVENT
if self.query.breakdownFilter.breakdown_type == "person":
property_type = PropertyDefinition.Type.PERSON
elif self.query.breakdownFilter.breakdown_type == "group":
property_type = PropertyDefinition.Type.GROUP
else:
property_type = PropertyDefinition.Type.EVENT

field_type = self._event_property(
self.query.breakdownFilter.breakdown,
property_type,
self.query.breakdownFilter.breakdown_group_type_index,
)
field_type = self._event_property(
self.query.breakdownFilter.breakdown,
property_type,
self.query.breakdownFilter.breakdown_group_type_index,
)
return field_type == "Boolean"

def _convert_boolean(self, value: Any):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -782,30 +782,6 @@
AND "posthog_persondistinctid"."team_id" = 2) /*controller='project_session_recordings-list',route='api/projects/%28%3FP%3Cparent_lookup_team_id%3E%5B%5E/.%5D%2B%29/session_recordings/%3F%24'*/
'''
# ---
# name: TestSessionRecordings.test_get_session_recordings.36
'''
SELECT "posthog_persondistinctid"."id",
"posthog_persondistinctid"."team_id",
"posthog_persondistinctid"."person_id",
"posthog_persondistinctid"."distinct_id",
"posthog_persondistinctid"."version",
"posthog_person"."id",
"posthog_person"."created_at",
"posthog_person"."properties_last_updated_at",
"posthog_person"."properties_last_operation",
"posthog_person"."team_id",
"posthog_person"."properties",
"posthog_person"."is_user_id",
"posthog_person"."is_identified",
"posthog_person"."uuid",
"posthog_person"."version"
FROM "posthog_persondistinctid"
INNER JOIN "posthog_person" ON ("posthog_persondistinctid"."person_id" = "posthog_person"."id")
WHERE ("posthog_persondistinctid"."distinct_id" IN ('user2',
'user_one_0')
AND "posthog_persondistinctid"."team_id" = 2) /*controller='project_session_recordings-list',route='api/projects/%28%3FP%3Cparent_lookup_team_id%3E%5B%5E/.%5D%2B%29/session_recordings/%3F%24'*/
'''
# ---
# name: TestSessionRecordings.test_get_session_recordings.4
'''
SELECT "posthog_team"."id",
Expand Down
Loading