Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 packages/db/src/services/conversion.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Comment on lines +121 to +131

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

This still misses profile-filter-only conversion queries.

Line 127 fixes ambiguous events.properties[...], but profileJoin is still only enabled for profile breakdowns at Lines 61-98. In the reported case where an event filter includes profile.* and another includes properties.*, this path now emits profile.properties[...] plus events.properties[...], and the query still 500s unless a profile breakdown also happens to be present. Funnel already handles this by joining profiles when either filters or breakdowns reference profile.; conversion needs the same gating here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/db/src/services/conversion.service.ts` around lines 121 - 131, The
conversion query still fails for profile-filter-only cases because profile joins
are gated only by breakdowns. Update the profile join condition in
conversion.service’s conversion query builder so it also enables the profiles
join when either event’s filters reference profile fields, matching the funnel
logic. Use the existing getEventFiltersWhereClause / profileJoin / breakdown
handling in the conversion service to detect profile.* filters and ensure the
query joins profiles whenever profile-based filters or breakdowns are present,
not just when a profile breakdown is selected.

).join(' AND ');

const funnelWindowSeconds = funnelWindow * 3600;
Expand Down
8 changes: 7 additions & 1 deletion packages/db/src/services/funnel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ', '');
});
Expand Down