diff --git a/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java b/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java index b4c82f790..cc7d86bc1 100644 --- a/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java +++ b/src/main/java/io/ebeaninternal/server/deploy/FormulaPropertyPath.java @@ -10,7 +10,7 @@ import java.util.regex.Pattern; class FormulaPropertyPath { - private static final String[] AGG_FUNCTIONS = {"count","max","min","avg"}; + private static final String[] AGG_FUNCTIONS = {"count", "max", "min", "avg"}; private static final Pattern pattern = Pattern.compile("([a-zA-Z]*)\\((.*)\\)"); @@ -41,7 +41,7 @@ class FormulaPropertyPath { } private String trimDistinct(String propertyName) { - if (propertyName.startsWith(DISTINCT_)){ + if (propertyName.startsWith(DISTINCT_)) { countDistinct = true; return propertyName.substring(DISTINCT_.length()); } else { @@ -67,19 +67,22 @@ class FormulaPropertyPath { ScalarType scalarType; if (isCount()) { - // count maps to Long / BIGINT scalarType = descriptor.getScalarType(Types.BIGINT); + + } else if (isConcat()) { + scalarType = descriptor.getScalarType(Types.VARCHAR); + } else { // determine scalarType based on first property found by parser if (firstProp != null) { scalarType = firstProp.getBeanProperty().getScalarType(); } else { - throw new IllegalStateException("unable to determine scalarType of formula [" + formula + "] for type " + descriptor+" - maybe use a cast like ::String ?"); + throw new IllegalStateException("unable to determine scalarType of formula [" + formula + "] for type " + descriptor + " - maybe use a cast like ::String ?"); } } String parsedAggregation = buildFormula(parsed); - return new DynamicPropertyAggregationFormula(formula, scalarType, parsedAggregation, isAggregate(),null); + return new DynamicPropertyAggregationFormula(formula, scalarType, parsedAggregation, isAggregate(), null); } private boolean isAggregate() { @@ -93,9 +96,9 @@ class FormulaPropertyPath { private String buildFormula(String parsed) { if (countDistinct) { - return "count(distinct "+parsed+")"; + return "count(distinct " + parsed + ")"; } else { - return outerFunction +"("+parsed+")"; + return outerFunction + "(" + parsed + ")"; } } @@ -103,4 +106,8 @@ class FormulaPropertyPath { return outerFunction.equals("count"); } + private boolean isConcat() { + return outerFunction.equals("concat"); + } + } diff --git a/src/test/java/org/tests/query/aggregation/TestAggregationCount.java b/src/test/java/org/tests/query/aggregation/TestAggregationCount.java index 6a0c4404a..0ace4031c 100644 --- a/src/test/java/org/tests/query/aggregation/TestAggregationCount.java +++ b/src/test/java/org/tests/query/aggregation/TestAggregationCount.java @@ -402,4 +402,25 @@ public class TestAggregationCount extends BaseTestCase { assertThat(sql.get(0)).contains("select concat(t0.last_name,', ',t0.first_name) from contact t0 where t0.phone is null order by t0.last_name"); } + @Test + public void concat_expectString() { + + ResetBasicData.reset(); + + LoggedSqlCollector.start(); + + List names = + + Ebean.find(Contact.class) + .select("concat(updtime,', ',firstName)") + .where().isNull("phone") + .orderBy().asc("lastName") + .findSingleAttributeList(); + + assertThat(names).isNotEmpty(); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql.get(0)).contains("select concat(t0.updtime,', ',t0.first_name) from contact t0"); + } + }