diff --git a/packages/db/src/services/conversion.service.ts b/packages/db/src/services/conversion.service.ts index 347191b33..fc721722d 100644 --- a/packages/db/src/services/conversion.service.ts +++ b/packages/db/src/services/conversion.service.ts @@ -118,11 +118,17 @@ export class ConversionService { const eventA = events[0]!; const eventB = events[1]!; + // Qualify with 'events' so event-level `properties[...]` becomes + // `events.properties[...]` — required when the conversion query also + // joins the profiles table (which exposes a `properties` column). + // Without the qualifier ClickHouse fails with "ambiguous identifier + // 'properties'" whenever a step filters on properties.X while a + // breakdown is on profile.properties.Y. const whereA = Object.values( - getEventFiltersWhereClause(eventA.filters, projectId), + getEventFiltersWhereClause(eventA.filters, projectId, 'events'), ).join(' AND '); const whereB = Object.values( - getEventFiltersWhereClause(eventB.filters, projectId), + getEventFiltersWhereClause(eventB.filters, projectId, 'events'), ).join(' AND '); const funnelWindowSeconds = funnelWindow * 3600; diff --git a/packages/db/src/services/funnel.service.ts b/packages/db/src/services/funnel.service.ts index 442c34df5..5a9ce8335 100644 --- a/packages/db/src/services/funnel.service.ts +++ b/packages/db/src/services/funnel.service.ts @@ -42,7 +42,13 @@ export class FunnelService { getFunnelConditions(events: IChartEvent[] = [], projectId?: string): string[] { return events.map((event) => { const { sb, getWhere } = createSqlBuilder(); - sb.where = getEventFiltersWhereClause(event.filters, projectId); + // Qualify with 'events' so event-level `properties[...]` becomes + // `events.properties[...]` — required because the funnel CTE may join + // the profiles table (which also exposes a `properties` column). + // Without the qualifier ClickHouse fails with "ambiguous identifier + // 'properties'" whenever a step filters on properties.X while another + // step filters on profile.properties.Y. + sb.where = getEventFiltersWhereClause(event.filters, projectId, 'events'); sb.where.name = `events.name = ${sqlstring.escape(event.name)}`; return getWhere().replace('WHERE ', ''); });