From d9da73e8d16ddf229e8b8c202085c9a8881de9d7 Mon Sep 17 00:00:00 2001 From: Eric Duong Date: Tue, 2 Apr 2024 12:36:24 -0400 Subject: [PATCH] feat(data-warehouse): make separate property type in taxonomic filter for data warehouse person properties (#21169) * make separate property type in popup * add flag * change type * use separate filter type * add types * more types * more typing * more types * restore --- .../lib/components/PropertyFilters/utils.ts | 5 +++ .../TaxonomicFilter/InfiniteList.tsx | 4 +- .../TaxonomicFilter/taxonomicFilterLogic.tsx | 13 ++++++ .../lib/components/TaxonomicFilter/types.ts | 1 + .../nodes/InsightViz/GlobalAndOrFilters.tsx | 6 +++ .../queries/nodes/InsightViz/TrendsSeries.tsx | 3 ++ frontend/src/queries/schema.json | 29 +++++++++++- .../external/dataWarehouseJoinsLogic.ts | 44 ++++++++++++++++++- frontend/src/types.ts | 7 +++ plugin-server/src/types.ts | 16 ++++++- posthog/hogql/property.py | 8 +++- posthog/models/property/property.py | 1 + posthog/schema.py | 42 ++++++++++++++++++ posthog/types.py | 2 + 14 files changed, 175 insertions(+), 6 deletions(-) diff --git a/frontend/src/lib/components/PropertyFilters/utils.ts b/frontend/src/lib/components/PropertyFilters/utils.ts index 824ddd6756b9a..255c8428ba8ba 100644 --- a/frontend/src/lib/components/PropertyFilters/utils.ts +++ b/frontend/src/lib/components/PropertyFilters/utils.ts @@ -101,6 +101,7 @@ export const PROPERTY_FILTER_TYPE_TO_TAXONOMIC_FILTER_GROUP_TYPE: Omit< [PropertyFilterType.HogQL]: TaxonomicFilterGroupType.HogQLExpression, [PropertyFilterType.Group]: TaxonomicFilterGroupType.GroupsPrefix, [PropertyFilterType.DataWarehouse]: TaxonomicFilterGroupType.DataWarehouse, + [PropertyFilterType.DataWarehousePersonProperty]: TaxonomicFilterGroupType.DataWarehousePersonProperties, } export function formatPropertyLabel( @@ -332,6 +333,10 @@ export function taxonomicFilterTypeToPropertyFilterType( return PropertyFilterType.DataWarehouse } + if (filterType == TaxonomicFilterGroupType.DataWarehousePersonProperties) { + return PropertyFilterType.DataWarehousePersonProperty + } + return Object.entries(propertyFilterMapping).find(([, v]) => v === filterType)?.[0] as | PropertyFilterType | undefined diff --git a/frontend/src/lib/components/TaxonomicFilter/InfiniteList.tsx b/frontend/src/lib/components/TaxonomicFilter/InfiniteList.tsx index 8e0237d36f252..ab03c6f9721c0 100644 --- a/frontend/src/lib/components/TaxonomicFilter/InfiniteList.tsx +++ b/frontend/src/lib/components/TaxonomicFilter/InfiniteList.tsx @@ -222,7 +222,9 @@ export function InfiniteList({ popupAnchorElement }: InfiniteListProps): JSX.Ele
canSelectItem(listGroupType) && selectItem(group, itemValue ?? null, item)} + onClick={() => { + return canSelectItem(listGroupType) && selectItem(group, itemValue ?? null, item) + }} > {renderItemContents({ item, diff --git a/frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx b/frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx index cc3e727f7b10d..966b33c5527ed 100644 --- a/frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx +++ b/frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.tsx @@ -15,6 +15,7 @@ import { IconCohort } from 'lib/lemon-ui/icons' import { CORE_FILTER_DEFINITIONS_BY_GROUP } from 'lib/taxonomy' import { capitalizeFirstLetter, pluralize, toParams } from 'lib/utils' import { getEventDefinitionIcon, getPropertyDefinitionIcon } from 'scenes/data-management/events/DefinitionHeader' +import { dataWarehouseJoinsLogic } from 'scenes/data-warehouse/external/dataWarehouseJoinsLogic' import { dataWarehouseSceneLogic } from 'scenes/data-warehouse/external/dataWarehouseSceneLogic' import { DataWarehouseTableType } from 'scenes/data-warehouse/types' import { experimentsLogic } from 'scenes/experiments/experimentsLogic' @@ -86,6 +87,8 @@ export const taxonomicFilterLogic = kea([ ['allGroupProperties'], dataWarehouseSceneLogic, ['externalTables'], + dataWarehouseJoinsLogic, + ['columnsJoinedToPersons'], ], }), actions(() => ({ @@ -225,6 +228,16 @@ export const taxonomicFilterLogic = kea([ getPopoverHeader: () => 'Data Warehouse Column', getIcon: () => , }, + { + name: 'Data Warehouse Person Properties', + searchPlaceholder: 'person properties from data warehouse tables', + type: TaxonomicFilterGroupType.DataWarehousePersonProperties, + logic: dataWarehouseJoinsLogic, + value: 'columnsJoinedToPersons', + getName: (personProperty: PersonProperty) => personProperty.name, + getValue: (personProperty: PersonProperty) => personProperty.id, + getPopoverHeader: () => 'Data Warehouse Person Property', + }, { name: 'Autocapture elements', searchPlaceholder: 'autocapture elements', diff --git a/frontend/src/lib/components/TaxonomicFilter/types.ts b/frontend/src/lib/components/TaxonomicFilter/types.ts index 964847c6eacaf..8b46784a19b7e 100644 --- a/frontend/src/lib/components/TaxonomicFilter/types.ts +++ b/frontend/src/lib/components/TaxonomicFilter/types.ts @@ -85,6 +85,7 @@ export enum TaxonomicFilterGroupType { CohortsWithAllUsers = 'cohorts_with_all', DataWarehouse = 'data_warehouse', DataWarehouseProperties = 'data_warehouse_properties', + DataWarehousePersonProperties = 'data_warehouse_person_properties', Elements = 'elements', Events = 'events', EventProperties = 'event_properties', diff --git a/frontend/src/queries/nodes/InsightViz/GlobalAndOrFilters.tsx b/frontend/src/queries/nodes/InsightViz/GlobalAndOrFilters.tsx index bd755cb3bd5e7..8485b9a71ee84 100644 --- a/frontend/src/queries/nodes/InsightViz/GlobalAndOrFilters.tsx +++ b/frontend/src/queries/nodes/InsightViz/GlobalAndOrFilters.tsx @@ -1,5 +1,7 @@ import { useActions, useValues } from 'kea' import { TaxonomicFilterGroupType } from 'lib/components/TaxonomicFilter/types' +import { FEATURE_FLAGS } from 'lib/constants' +import { featureFlagLogic } from 'lib/logic/featureFlagLogic' import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic' import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils' @@ -16,6 +18,7 @@ export function GlobalAndOrFilters({ insightProps }: EditorFilterProps): JSX.Ele const { groupsTaxonomicTypes } = useValues(groupsModel) const { isTrends, querySource, isDataWarehouseSeries } = useValues(insightVizDataLogic(insightProps)) const { updateQuerySource } = useActions(insightVizDataLogic(insightProps)) + const { featureFlags } = useValues(featureFlagLogic) const taxonomicGroupTypes = [ TaxonomicFilterGroupType.EventProperties, @@ -26,6 +29,9 @@ export function GlobalAndOrFilters({ insightProps }: EditorFilterProps): JSX.Ele TaxonomicFilterGroupType.Elements, ...(isTrends ? [TaxonomicFilterGroupType.Sessions] : []), TaxonomicFilterGroupType.HogQLExpression, + ...(featureFlags[FEATURE_FLAGS.DATA_WAREHOUSE] && featureFlags[FEATURE_FLAGS.HOGQL_INSIGHTS] + ? [TaxonomicFilterGroupType.DataWarehousePersonProperties] + : []), ] return ( diff --git a/frontend/src/queries/nodes/InsightViz/TrendsSeries.tsx b/frontend/src/queries/nodes/InsightViz/TrendsSeries.tsx index fc65ff00a670d..38b96c2162aca 100644 --- a/frontend/src/queries/nodes/InsightViz/TrendsSeries.tsx +++ b/frontend/src/queries/nodes/InsightViz/TrendsSeries.tsx @@ -37,6 +37,9 @@ export function TrendsSeries(): JSX.Element | null { ...(isTrends ? [TaxonomicFilterGroupType.Sessions] : []), TaxonomicFilterGroupType.HogQLExpression, TaxonomicFilterGroupType.DataWarehouseProperties, + ...(featureFlags[FEATURE_FLAGS.DATA_WAREHOUSE] && featureFlags[FEATURE_FLAGS.HOGQL_INSIGHTS] + ? [TaxonomicFilterGroupType.DataWarehousePersonProperties] + : []), ] if (!isInsightQueryNode(querySource)) { diff --git a/frontend/src/queries/schema.json b/frontend/src/queries/schema.json index 4724402ff1a79..c846f43882f88 100644 --- a/frontend/src/queries/schema.json +++ b/frontend/src/queries/schema.json @@ -277,6 +277,9 @@ }, { "$ref": "#/definitions/DataWarehousePropertyFilter" + }, + { + "$ref": "#/definitions/DataWarehousePersonPropertyFilter" } ] }, @@ -862,6 +865,29 @@ "required": ["distinct_id_field", "id", "id_field", "kind", "table_name", "timestamp_field"], "type": "object" }, + "DataWarehousePersonPropertyFilter": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "label": { + "type": "string" + }, + "operator": { + "$ref": "#/definitions/PropertyOperator" + }, + "type": { + "const": "data_warehouse_person_property", + "type": "string" + }, + "value": { + "$ref": "#/definitions/PropertyFilterValue" + } + }, + "required": ["key", "operator", "type"], + "type": "object" + }, "DataWarehousePropertyFilter": { "additionalProperties": false, "properties": { @@ -3528,7 +3554,8 @@ "recording", "group", "hogql", - "data_warehouse" + "data_warehouse", + "data_warehouse_person_property" ], "type": "string" }, diff --git a/frontend/src/scenes/data-warehouse/external/dataWarehouseJoinsLogic.ts b/frontend/src/scenes/data-warehouse/external/dataWarehouseJoinsLogic.ts index b5f493b2d7f17..b34bc82773378 100644 --- a/frontend/src/scenes/data-warehouse/external/dataWarehouseJoinsLogic.ts +++ b/frontend/src/scenes/data-warehouse/external/dataWarehouseJoinsLogic.ts @@ -1,10 +1,13 @@ -import { afterMount, kea, path } from 'kea' +import { afterMount, connect, kea, path, selectors } from 'kea' import { loaders } from 'kea-loaders' import api from 'lib/api' +import { capitalizeFirstLetter } from 'lib/utils' -import { DataWarehouseViewLink } from '~/types' +import { DatabaseSchemaQueryResponseField } from '~/queries/schema' +import { DataWarehouseViewLink, PropertyDefinition, PropertyType } from '~/types' import type { dataWarehouseJoinsLogicType } from './dataWarehouseJoinsLogicType' +import { dataWarehouseSceneLogic } from './dataWarehouseSceneLogic' export const dataWarehouseJoinsLogic = kea([ path(['scenes', 'data-warehouse', 'external', 'dataWarehouseJoinsLogic']), @@ -19,6 +22,43 @@ export const dataWarehouseJoinsLogic = kea([ }, ], }), + connect(() => ({ + values: [dataWarehouseSceneLogic, ['externalTablesMap']], + })), + selectors({ + personTableJoins: [(s) => [s.joins], (joins) => joins.filter((join) => join.source_table_name === 'persons')], + tablesJoinedToPersons: [ + (s) => [s.externalTablesMap, s.personTableJoins], + (externalTablesMap, personTableJoins) => { + return personTableJoins.map((join: DataWarehouseViewLink) => { + // valid join should have a joining table name + const table = externalTablesMap[join.joining_table_name as string] + return { + table, + join, + } + }) + }, + ], + columnsJoinedToPersons: [ + (s) => [s.tablesJoinedToPersons], + (tablesJoinedToPersons) => { + return tablesJoinedToPersons.reduce((acc, { table, join }) => { + if (table) { + acc.push( + ...table.columns.map((column: DatabaseSchemaQueryResponseField) => ({ + id: join.field_name + ': ' + column.key, + name: join.field_name + ': ' + column.key, + table: join.field_name, + property_type: capitalizeFirstLetter(column.type) as PropertyType, + })) + ) + } + return acc + }, [] as PropertyDefinition[]) + }, + ], + }), afterMount(({ actions }) => { actions.loadJoins() }), diff --git a/frontend/src/types.ts b/frontend/src/types.ts index 56708d5ae1d85..74c8370a008d1 100644 --- a/frontend/src/types.ts +++ b/frontend/src/types.ts @@ -652,6 +652,7 @@ export enum PropertyFilterType { Group = 'group', HogQL = 'hogql', DataWarehouse = 'data_warehouse', + DataWarehousePersonProperty = 'data_warehouse_person_property', } /** Sync with plugin-server/src/types.ts */ @@ -679,6 +680,11 @@ export interface DataWarehousePropertyFilter extends BasePropertyFilter { operator: PropertyOperator } +export interface DataWarehousePersonPropertyFilter extends BasePropertyFilter { + type: PropertyFilterType.DataWarehousePersonProperty + operator: PropertyOperator +} + /** Sync with plugin-server/src/types.ts */ export interface ElementPropertyFilter extends BasePropertyFilter { type: PropertyFilterType.Element @@ -735,6 +741,7 @@ export type AnyPropertyFilter = | HogQLPropertyFilter | EmptyPropertyFilter | DataWarehousePropertyFilter + | DataWarehousePersonPropertyFilter export type AnyFilterLike = AnyPropertyFilter | PropertyGroupFilter | PropertyGroupFilterValue diff --git a/plugin-server/src/types.ts b/plugin-server/src/types.ts index d8a46819fad9b..df2efa8daa5f7 100644 --- a/plugin-server/src/types.ts +++ b/plugin-server/src/types.ts @@ -875,6 +875,14 @@ export interface PersonPropertyFilter extends PropertyFilterWithOperator { type: 'person' } +export interface DataWarehousePropertyFilter extends PropertyFilterWithOperator { + type: 'data_warehouse' +} + +export interface DataWarehousePersonPropertyFilter extends PropertyFilterWithOperator { + type: 'data_warehouse_person_property' +} + /** Sync with posthog/frontend/src/types.ts */ export interface ElementPropertyFilter extends PropertyFilterWithOperator { type: 'element' @@ -890,7 +898,13 @@ export interface CohortPropertyFilter extends PropertyFilterBase { } /** Sync with posthog/frontend/src/types.ts */ -export type PropertyFilter = EventPropertyFilter | PersonPropertyFilter | ElementPropertyFilter | CohortPropertyFilter +export type PropertyFilter = + | EventPropertyFilter + | PersonPropertyFilter + | ElementPropertyFilter + | CohortPropertyFilter + | DataWarehousePropertyFilter + | DataWarehousePersonPropertyFilter /** Sync with posthog/frontend/src/types.ts */ export enum StringMatching { diff --git a/posthog/hogql/property.py b/posthog/hogql/property.py index 07af0b548cc7a..c56ca7fc3aef7 100644 --- a/posthog/hogql/property.py +++ b/posthog/hogql/property.py @@ -138,6 +138,7 @@ def property_to_expr( or property.type == "person" or property.type == "group" or property.type == "data_warehouse" + or property.type == "data_warehouse_person_property" or property.type == "session" ): if scope == "person" and property.type != "person": @@ -146,9 +147,14 @@ def property_to_expr( ) operator = cast(Optional[PropertyOperator], property.operator) or PropertyOperator.exact value = property.value - if property.type == "person" and scope != "person": chain = ["person", "properties"] + elif property.type == "data_warehouse_person_property": + if isinstance(property.value, str): + table, value = property.value.split(": ") + chain = ["person", table] + else: + raise NotImplementedException("Data warehouse person property filter value must be a string") elif property.type == "group": chain = [f"group_{property.group_type_index}", "properties"] elif property.type == "data_warehouse": diff --git a/posthog/models/property/property.py b/posthog/models/property/property.py index d0e0f94439cf5..cf5402f5afbdb 100644 --- a/posthog/models/property/property.py +++ b/posthog/models/property/property.py @@ -42,6 +42,7 @@ class BehavioralPropertyType(str, Enum): "session", "hogql", "data_warehouse", + "data_warehouse_person_property", ] PropertyName = str diff --git a/posthog/schema.py b/posthog/schema.py index aeff2dc563c9b..9cd8c96a64506 100644 --- a/posthog/schema.py +++ b/posthog/schema.py @@ -651,6 +651,7 @@ class PropertyFilterType(str, Enum): group = "group" hogql = "hogql" data_warehouse = "data_warehouse" + data_warehouse_person_property = "data_warehouse_person_property" class PropertyMathType(str, Enum): @@ -1131,6 +1132,17 @@ class ChartSettings(BaseModel): yAxis: Optional[List[ChartAxis]] = None +class DataWarehousePersonPropertyFilter(BaseModel): + model_config = ConfigDict( + extra="forbid", + ) + key: str + label: Optional[str] = None + operator: PropertyOperator + type: Literal["data_warehouse_person_property"] = "data_warehouse_person_property" + value: Optional[Union[str, float, List[Union[str, float]]]] = None + + class DataWarehousePropertyFilter(BaseModel): model_config = ConfigDict( extra="forbid", @@ -1745,6 +1757,7 @@ class DashboardFilter(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = None @@ -1770,6 +1783,7 @@ class DataWarehouseNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -1800,6 +1814,7 @@ class DataWarehouseNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -1837,6 +1852,7 @@ class EntityNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -1865,6 +1881,7 @@ class EntityNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -1891,6 +1908,7 @@ class EventsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -1921,6 +1939,7 @@ class EventsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -1950,6 +1969,7 @@ class EventsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -1975,6 +1995,7 @@ class EventsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -2002,6 +2023,7 @@ class FunnelExclusionActionsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -2033,6 +2055,7 @@ class FunnelExclusionActionsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -2059,6 +2082,7 @@ class FunnelExclusionEventsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -2091,6 +2115,7 @@ class FunnelExclusionEventsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -2117,6 +2142,7 @@ class HogQLFilters(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = None @@ -2157,6 +2183,7 @@ class PersonsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -2180,6 +2207,7 @@ class PersonsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -2207,6 +2235,7 @@ class PropertyGroupFilterValue(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ], ] ] @@ -2314,6 +2343,7 @@ class ActionsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field( @@ -2343,6 +2373,7 @@ class ActionsNode(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = Field(default=None, description="Properties configurable in the interface") @@ -2434,6 +2465,7 @@ class RetentionQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2471,6 +2503,7 @@ class StickinessQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2514,6 +2547,7 @@ class TrendsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2570,6 +2604,7 @@ class FilterType(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2610,6 +2645,7 @@ class FunnelsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2646,6 +2682,7 @@ class InsightsQueryBase(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2684,6 +2721,7 @@ class LifecycleQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2729,6 +2767,7 @@ class PathsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ], PropertyGroupFilter, @@ -2844,6 +2883,7 @@ class FunnelCorrelationActorsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = None @@ -2880,6 +2920,7 @@ class ActorsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = None @@ -2901,6 +2942,7 @@ class ActorsQuery(BaseModel): HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] ] ] = None diff --git a/posthog/types.py b/posthog/types.py index 3b434f16417ac..466b537bdea6b 100644 --- a/posthog/types.py +++ b/posthog/types.py @@ -13,6 +13,7 @@ EventPropertyFilter, EventsNode, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, FeaturePropertyFilter, FunnelCorrelationActorsQuery, FunnelExclusionActionsNode, @@ -58,6 +59,7 @@ HogQLPropertyFilter, EmptyPropertyFilter, DataWarehousePropertyFilter, + DataWarehousePersonPropertyFilter, ] EntityNode: TypeAlias = Union[EventsNode, ActionsNode, DataWarehouseNode]