Skip to content

Commit cecb17c

Browse files
fix: alias wrapped ClickHouse aggregate text columns to keep result-set label
1 parent 791e796 commit cecb17c

2 files changed

Lines changed: 16 additions & 4 deletions

File tree

dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/event/data/AbstractJdbcEventAnalyticsManager.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -703,14 +703,24 @@ protected ColumnAndAlias getColumnAndAlias(
703703
&& hasOrderByClauseForQueryItem(queryItem, params)) {
704704
return getColumnAndAliasWithNullIfFunction(queryItem);
705705
} else if (queryItem.isText() && isAggregated) {
706-
// ClickHouse stores an empty string value as '' rather than NULL, so a raw GROUP BY would
707-
// produce a '' bucket and return '' instead of NULL. nullIfEmpty normalises '' to
706+
// ClickHouse stores an absent string value as '' rather than NULL, so a raw GROUP BY would
707+
// produce a spurious '' bucket and return '' instead of NULL. nullIfEmpty normalises '' to
708708
// NULL (no-op on Postgres/Doris). The same expression is used for SELECT and GROUP BY so the
709709
// bucket key and the displayed value stay aligned.
710-
String column = sqlBuilder.nullIfEmpty(getColumn(queryItem));
710+
String rawColumn = getColumn(queryItem);
711+
String column = sqlBuilder.nullIfEmpty(rawColumn);
712+
713+
if (column.equals(rawColumn)) {
714+
// No normalisation applied (Postgres/Doris): keep the original rendering unchanged.
715+
return getColumnAndAlias(queryItem, isGroupByClause, "");
716+
}
717+
718+
// ClickHouse: the nullif wrapper drops the implicit column label, so alias it with the item
719+
// name the row builder looks up.
711720
return isGroupByClause
712721
? ColumnAndAlias.ofColumn(column)
713-
: ColumnAndAlias.ofColumnAndAlias(column, getAlias(queryItem).orElse(""));
722+
: ColumnAndAlias.ofColumnAndAlias(
723+
column, getAlias(queryItem).orElse(queryItem.getItemName()));
714724
} else {
715725
return getColumnAndAlias(queryItem, isGroupByClause, "");
716726
}

dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/event/data/EventAnalyticsManagerTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,8 @@ void verifyAggregatedTextDimensionWrapsEmptyStringAsNullForClickHouse() {
10481048
String generatedSql = sql.getValue().toLowerCase();
10491049
// SELECT and GROUP BY must both reference the nullif-wrapped column so '' folds into NULL.
10501050
assertThat(countMatches(generatedSql, "nullif(ax.\"fwiaetyvegk\", '')"), is(2));
1051+
// The SELECT column must keep an alias matching the item name so the row builder can read it.
1052+
assertThat(generatedSql, containsString("nullif(ax.\"fwiaetyvegk\", '') as \"fwiaetyvegk\""));
10511053
}
10521054

10531055
@Test

0 commit comments

Comments
 (0)