Skip to content

Commit b64aca1

Browse files
committed
Support "count(distinct expression)"
1 parent d734f13 commit b64aca1

File tree

5 files changed

+78
-36
lines changed

5 files changed

+78
-36
lines changed

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/expression/AggregateFunction.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package org.seasar.doma.jdbc.criteria.expression;
22

3-
import java.util.Objects;
4-
import java.util.Optional;
5-
import java.util.function.BiFunction;
6-
import java.util.function.Function;
73
import org.seasar.doma.internal.jdbc.scalar.BasicScalar;
84
import org.seasar.doma.internal.jdbc.scalar.Scalar;
95
import org.seasar.doma.internal.jdbc.sql.ScalarInParameter;
@@ -15,6 +11,11 @@
1511
import org.seasar.doma.wrapper.LongWrapper;
1612
import org.seasar.doma.wrapper.Wrapper;
1713

14+
import java.util.Objects;
15+
import java.util.Optional;
16+
import java.util.function.BiFunction;
17+
import java.util.function.Function;
18+
1819
public interface AggregateFunction<PROPERTY> extends PropertyMetamodel<PROPERTY> {
1920
Asterisk Asterisk = new Asterisk();
2021

@@ -83,8 +84,15 @@ public void accept(PropertyMetamodel.Visitor visitor) {
8384
class Count extends AbstractFunction<Long> {
8485
private final LongEntityPropertyType propertyType = new LongEntityPropertyType();
8586

87+
public final boolean distinct;
88+
8689
public Count(PropertyMetamodel<?> argument) {
90+
this(argument, false);
91+
}
92+
93+
public Count(PropertyMetamodel<?> argument, boolean distinct) {
8794
super("count", argument);
95+
this.distinct = distinct;
8896
}
8997

9098
@Override

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/expression/Expressions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ public static AggregateFunction.Count count(PropertyMetamodel<?> propertyMetamod
157157
return new AggregateFunction.Count(propertyMetamodel);
158158
}
159159

160+
public static AggregateFunction.Count countDistinct(PropertyMetamodel<?> propertyMetamodel) {
161+
Objects.requireNonNull(propertyMetamodel);
162+
return new AggregateFunction.Count(propertyMetamodel, true);
163+
}
164+
160165
public static <PROPERTY> AggregateFunction.Max<PROPERTY> max(
161166
PropertyMetamodel<PROPERTY> propertyMetamodel) {
162167
Objects.requireNonNull(propertyMetamodel);

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/query/BuilderSupport.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package org.seasar.doma.jdbc.criteria.query;
22

3-
import java.util.List;
4-
import java.util.Objects;
5-
import java.util.function.BiFunction;
6-
import java.util.function.Function;
73
import org.seasar.doma.DomaException;
84
import org.seasar.doma.expr.ExpressionFunctions;
95
import org.seasar.doma.internal.jdbc.sql.BasicInParameter;
@@ -26,6 +22,11 @@
2622
import org.seasar.doma.message.Message;
2723
import org.seasar.doma.wrapper.StringWrapper;
2824

25+
import java.util.List;
26+
import java.util.Objects;
27+
import java.util.function.BiFunction;
28+
import java.util.function.Function;
29+
2930
public class BuilderSupport {
3031
private final Config config;
3132
private final Function<String, String> commenter;
@@ -534,7 +535,13 @@ public void visit(AggregateFunction.Avg<?> avg) {
534535

535536
@Override
536537
public void visit(AggregateFunction.Count count) {
537-
aggregateFunction(count.getName(), count.argument());
538+
buf.appendSql(count.getName());
539+
buf.appendSql("(");
540+
if (count.distinct) {
541+
buf.appendSql("distinct ");
542+
}
543+
count.argument().accept(this);
544+
buf.appendSql(")");
538545
}
539546

540547
@Override

doma-core/src/test/java/org/seasar/doma/jdbc/criteria/NativeSqlSelectTest.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
package org.seasar.doma.jdbc.criteria;
22

3-
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.avg;
5-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.concat;
6-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.count;
7-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.literal;
8-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.max;
9-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.min;
10-
import static org.seasar.doma.jdbc.criteria.expression.Expressions.sum;
11-
12-
import java.math.BigDecimal;
13-
import java.util.Arrays;
14-
import java.util.List;
153
import org.junit.jupiter.api.Test;
164
import org.seasar.doma.internal.jdbc.mock.MockConfig;
175
import org.seasar.doma.jdbc.CommentContext;
@@ -36,6 +24,20 @@
3624
import org.seasar.doma.jdbc.dialect.OracleDialect;
3725
import org.seasar.doma.jdbc.dialect.PostgresDialect;
3826

27+
import java.math.BigDecimal;
28+
import java.util.Arrays;
29+
import java.util.List;
30+
31+
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.avg;
33+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.concat;
34+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.count;
35+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.countDistinct;
36+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.literal;
37+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.max;
38+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.min;
39+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.sum;
40+
3941
class NativeSqlSelectTest {
4042

4143
private final NativeSql nativeSql = new NativeSql(new MockConfig());
@@ -933,6 +935,16 @@ void aggregateFunctions() {
933935
sql.getFormattedSql());
934936
}
935937

938+
@Test
939+
void aggregateFunction_countDistinct() {
940+
Emp_ e = new Emp_();
941+
Buildable<?> stmt = nativeSql.from(e).select(countDistinct(e.id));
942+
943+
Sql<?> sql = stmt.asSql();
944+
assertEquals(
945+
"select count(distinct t0_.ID) from EMP t0_", sql.getFormattedSql());
946+
}
947+
936948
@Test
937949
void union() {
938950
Emp_ e = new Emp_();

test-criteria/src/test/java/example/NativeSqlSelectTest.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
package example;
22

3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.ExtendWith;
5+
import org.seasar.doma.jdbc.Config;
6+
import org.seasar.doma.jdbc.SqlLogType;
7+
import org.seasar.doma.jdbc.criteria.NativeSql;
8+
import org.seasar.doma.jdbc.criteria.metamodel.PropertyMetamodel;
9+
import org.seasar.doma.jdbc.criteria.statement.EmptyWhereClauseException;
10+
import org.seasar.doma.jdbc.criteria.tuple.Row;
11+
import org.seasar.doma.jdbc.criteria.tuple.Tuple2;
12+
import org.seasar.doma.jdbc.criteria.tuple.Tuple3;
13+
14+
import java.math.BigDecimal;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.stream.Stream;
18+
319
import static java.util.stream.Collectors.counting;
420
import static java.util.stream.Collectors.groupingBy;
521
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -11,28 +27,14 @@
1127
import static org.seasar.doma.jdbc.criteria.expression.Expressions.add;
1228
import static org.seasar.doma.jdbc.criteria.expression.Expressions.concat;
1329
import static org.seasar.doma.jdbc.criteria.expression.Expressions.count;
30+
import static org.seasar.doma.jdbc.criteria.expression.Expressions.countDistinct;
1431
import static org.seasar.doma.jdbc.criteria.expression.Expressions.div;
1532
import static org.seasar.doma.jdbc.criteria.expression.Expressions.min;
1633
import static org.seasar.doma.jdbc.criteria.expression.Expressions.mod;
1734
import static org.seasar.doma.jdbc.criteria.expression.Expressions.mul;
1835
import static org.seasar.doma.jdbc.criteria.expression.Expressions.sub;
1936
import static org.seasar.doma.jdbc.criteria.expression.Expressions.sum;
2037

21-
import java.math.BigDecimal;
22-
import java.util.List;
23-
import java.util.Map;
24-
import java.util.stream.Stream;
25-
import org.junit.jupiter.api.Test;
26-
import org.junit.jupiter.api.extension.ExtendWith;
27-
import org.seasar.doma.jdbc.Config;
28-
import org.seasar.doma.jdbc.SqlLogType;
29-
import org.seasar.doma.jdbc.criteria.NativeSql;
30-
import org.seasar.doma.jdbc.criteria.metamodel.PropertyMetamodel;
31-
import org.seasar.doma.jdbc.criteria.statement.EmptyWhereClauseException;
32-
import org.seasar.doma.jdbc.criteria.tuple.Row;
33-
import org.seasar.doma.jdbc.criteria.tuple.Tuple2;
34-
import org.seasar.doma.jdbc.criteria.tuple.Tuple3;
35-
3638
@ExtendWith(Env.class)
3739
public class NativeSqlSelectTest {
3840

@@ -245,6 +247,14 @@ void aggregate() {
245247
assertEquals(0, salary.getValue().compareTo(new BigDecimal("29025")));
246248
}
247249

250+
@Test
251+
void aggregate_countDistinct() {
252+
Employee_ e = new Employee_();
253+
254+
Long count = nativeSql.from(e).select(countDistinct(e.departmentId)).fetchOne();
255+
assertEquals(3, count);
256+
}
257+
248258
@Test
249259
void groupBy() {
250260
Employee_ e = new Employee_();

0 commit comments

Comments
 (0)