@@ -186,6 +186,52 @@ void caseWithNullHandling() {
186186 assertThat ((Object ) result .getProperty ("category" )).isEqualTo ("unknown" );
187187 }
188188
189+ /**
190+ * Regression test for issue #3858:
191+ * Aggregation with CASE statement should not create implicit GROUP BY on variables inside the CASE.
192+ * When all RETURN items are aggregations, a single row must be returned.
193+ */
194+ @ Test
195+ void aggregationWithCaseNoImplicitGroupBy () {
196+ // Both count(loc) and sum(CASE...) are aggregations — no grouping keys exist.
197+ // Expected: single row {total: 3, pa: 2}
198+ final ResultSet results = database .query ("opencypher" ,
199+ "UNWIND [{state: 'NY'}, {state: 'PA'}, {state: 'PA'}] AS loc " +
200+ "RETURN count(loc) AS total, sum(CASE WHEN loc.state = 'PA' THEN 1 ELSE 0 END) AS pa" );
201+
202+ assertThat ((boolean ) results .hasNext ()).isTrue ();
203+ final Result result = results .next ();
204+ assertThat (((Number ) result .getProperty ("total" )).longValue ()).isEqualTo (3L );
205+ assertThat (((Number ) result .getProperty ("pa" )).longValue ()).isEqualTo (2L );
206+ assertThat ((boolean ) results .hasNext ()).isFalse ();
207+ }
208+
209+ /**
210+ * Regression test for issue #3858 (variant):
211+ * When RETURN has both aggregations and a non-aggregated grouping key,
212+ * the CASE arguments must not act as additional grouping keys.
213+ */
214+ @ Test
215+ void aggregationWithCaseAndGroupByKey () {
216+ // category is the real grouping key; sum(CASE...) must aggregate per category, not per loc.state
217+ final ResultSet results = database .query ("opencypher" ,
218+ "UNWIND [{state: 'NY', cat: 'A'}, {state: 'PA', cat: 'A'}, {state: 'PA', cat: 'B'}] AS loc " +
219+ "RETURN loc.cat AS category, sum(CASE WHEN loc.state = 'PA' THEN 1 ELSE 0 END) AS pa " +
220+ "ORDER BY category" );
221+
222+ assertThat ((boolean ) results .hasNext ()).isTrue ();
223+ final Result rowA = results .next ();
224+ assertThat ((Object ) rowA .getProperty ("category" )).isEqualTo ("A" );
225+ assertThat (((Number ) rowA .getProperty ("pa" )).longValue ()).isEqualTo (1L );
226+
227+ assertThat ((boolean ) results .hasNext ()).isTrue ();
228+ final Result rowB = results .next ();
229+ assertThat ((Object ) rowB .getProperty ("category" )).isEqualTo ("B" );
230+ assertThat (((Number ) rowB .getProperty ("pa" )).longValue ()).isEqualTo (1L );
231+
232+ assertThat ((boolean ) results .hasNext ()).isFalse ();
233+ }
234+
189235 @ Test
190236 void nestedCaseExpressions () {
191237 // Nested CASE expressions
0 commit comments