Skip to content

Commit e1d6aa5

Browse files
authored
chore | adding the support for function as an order by argument (#293)
* chore | adding the support for function as an order by argument
1 parent 1ab394f commit e1d6aa5

File tree

3 files changed

+74
-7
lines changed

3 files changed

+74
-7
lines changed

entity-service-impl/src/main/java/org/hypertrace/entity/query/service/converter/OrderByConverter.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import static com.google.common.base.Suppliers.memoize;
44
import static java.util.Collections.unmodifiableMap;
55
import static org.hypertrace.entity.query.service.v1.Expression.ValueCase.COLUMNIDENTIFIER;
6+
import static org.hypertrace.entity.query.service.v1.Expression.ValueCase.FUNCTION;
67
import static org.hypertrace.entity.query.service.v1.SortOrder.ASC;
78
import static org.hypertrace.entity.query.service.v1.SortOrder.DESC;
89

@@ -24,15 +25,18 @@
2425
import org.hypertrace.entity.query.service.v1.ColumnIdentifier;
2526
import org.hypertrace.entity.query.service.v1.Expression;
2627
import org.hypertrace.entity.query.service.v1.Expression.ValueCase;
28+
import org.hypertrace.entity.query.service.v1.Function;
2729
import org.hypertrace.entity.query.service.v1.OrderByExpression;
2830

2931
@Singleton
3032
@AllArgsConstructor(onConstructor_ = {@Inject})
3133
public class OrderByConverter implements Converter<List<OrderByExpression>, Sort> {
34+
3235
private static final Supplier<Map<org.hypertrace.entity.query.service.v1.SortOrder, SortOrder>>
3336
ORDER_MAP = memoize(OrderByConverter::getMapping);
3437
private final OneOfAccessor<Expression, ValueCase> expressionAccessor;
3538
private final AliasProvider<ColumnIdentifier> aliasProvider;
39+
private final AliasProvider<Function> functionAliasProvider;
3640

3741
@Override
3842
public Sort convert(final List<OrderByExpression> orders, final RequestContext requestContext)
@@ -50,14 +54,24 @@ public Sort convert(final List<OrderByExpression> orders, final RequestContext r
5054
private SortingSpec convert(final OrderByExpression orderBy) throws ConversionException {
5155
final Expression innerExpression = orderBy.getExpression();
5256

53-
final ColumnIdentifier identifier =
54-
expressionAccessor.access(
55-
innerExpression, innerExpression.getValueCase(), Set.of(COLUMNIDENTIFIER));
56-
final String alias = aliasProvider.getAlias(identifier);
57-
final IdentifierExpression identifierExpression = IdentifierExpression.of(alias);
57+
Object expression =
58+
this.expressionAccessor.access(
59+
innerExpression, innerExpression.getValueCase(), Set.of(COLUMNIDENTIFIER, FUNCTION));
60+
String alias;
61+
switch (innerExpression.getValueCase()) {
62+
case COLUMNIDENTIFIER:
63+
alias = aliasProvider.getAlias((ColumnIdentifier) expression);
64+
break;
65+
case FUNCTION:
66+
alias = functionAliasProvider.getAlias((Function) expression);
67+
break;
68+
default:
69+
throw new ConversionException(
70+
String.format("Unsupported expression type %s", innerExpression.getValueCase()));
71+
}
5872

73+
final IdentifierExpression identifierExpression = IdentifierExpression.of(alias);
5974
final SortOrder order = ORDER_MAP.get().get(orderBy.getOrder());
60-
6175
if (order == null) {
6276
throw new ConversionException(
6377
String.format("Cannot find sorting order %s", orderBy.getOrder()));
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.hypertrace.entity.query.service.converter.identifier;
2+
3+
import com.google.inject.Inject;
4+
import com.google.inject.Singleton;
5+
import lombok.AllArgsConstructor;
6+
import org.hypertrace.entity.query.service.converter.AliasProvider;
7+
import org.hypertrace.entity.query.service.v1.Function;
8+
import org.hypertrace.entity.service.util.StringUtils;
9+
10+
@Singleton
11+
@AllArgsConstructor(onConstructor_ = {@Inject})
12+
public class FunctionAliasProvider implements AliasProvider<Function> {
13+
14+
@Override
15+
public String getAlias(final Function function) {
16+
if (StringUtils.isNotBlank(function.getAlias())) {
17+
return function.getAlias();
18+
}
19+
20+
throw new IllegalArgumentException("Function alias is missing");
21+
}
22+
}

entity-service-impl/src/test/java/org/hypertrace/entity/query/service/converter/OrderByConverterTest.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44
import static org.junit.jupiter.api.Assertions.assertNotNull;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
56
import static org.mockito.quality.Strictness.LENIENT;
67

78
import java.util.List;
@@ -12,10 +13,12 @@
1213
import org.hypertrace.core.grpcutils.context.RequestContext;
1314
import org.hypertrace.entity.query.service.converter.accessor.ExpressionOneOfAccessor;
1415
import org.hypertrace.entity.query.service.converter.accessor.OneOfAccessor;
16+
import org.hypertrace.entity.query.service.converter.identifier.FunctionAliasProvider;
1517
import org.hypertrace.entity.query.service.converter.identifier.IdentifierAliasProvider;
1618
import org.hypertrace.entity.query.service.v1.ColumnIdentifier;
1719
import org.hypertrace.entity.query.service.v1.Expression;
1820
import org.hypertrace.entity.query.service.v1.Expression.ValueCase;
21+
import org.hypertrace.entity.query.service.v1.Function;
1922
import org.hypertrace.entity.query.service.v1.OrderByExpression;
2023
import org.junit.jupiter.api.BeforeEach;
2124
import org.junit.jupiter.api.Test;
@@ -35,6 +38,7 @@ class OrderByConverterTest {
3538
private Converter<List<OrderByExpression>, Sort> orderByConverter;
3639

3740
private final AliasProvider<ColumnIdentifier> aliasProvider = new IdentifierAliasProvider();
41+
private final AliasProvider<Function> functionAliasProvider = new FunctionAliasProvider();
3842
private final ColumnIdentifier columnIdentifier =
3943
ColumnIdentifier.newBuilder().setColumnName("Planet_Mars").build();
4044
private final IdentifierExpression identifierExpression = IdentifierExpression.of("Planet_Mars");
@@ -47,7 +51,8 @@ class OrderByConverterTest {
4751
@BeforeEach
4852
void setup() {
4953
OneOfAccessor<Expression, ValueCase> expressionAccessor = new ExpressionOneOfAccessor();
50-
orderByConverter = new OrderByConverter(expressionAccessor, aliasProvider);
54+
orderByConverter =
55+
new OrderByConverter(expressionAccessor, aliasProvider, functionAliasProvider);
5156
}
5257

5358
@Test
@@ -57,6 +62,32 @@ void testConvert() throws ConversionException {
5762
assertEquals(expected, orderByConverter.convert(List.of(orderByExpression), requestContext));
5863
}
5964

65+
@Test
66+
void testConvert_functionExpression() throws ConversionException {
67+
IdentifierExpression aliasExpression = IdentifierExpression.of("agg_count");
68+
OrderByExpression orderByExpressionWithAlias =
69+
OrderByExpression.newBuilder()
70+
.setExpression(
71+
Expression.newBuilder()
72+
.setFunction(Function.newBuilder().setAlias("agg_count").build()))
73+
.setOrder(org.hypertrace.entity.query.service.v1.SortOrder.ASC)
74+
.build();
75+
76+
Sort expected =
77+
Sort.builder().sortingSpec(SortingSpec.of(aliasExpression, SortOrder.ASC)).build();
78+
assertEquals(
79+
expected, orderByConverter.convert(List.of(orderByExpressionWithAlias), requestContext));
80+
81+
OrderByExpression orderByExpressionWithoutAlias =
82+
OrderByExpression.newBuilder()
83+
.setExpression(Expression.newBuilder().setFunction(Function.newBuilder().build()))
84+
.setOrder(org.hypertrace.entity.query.service.v1.SortOrder.ASC)
85+
.build();
86+
assertThrows(
87+
IllegalArgumentException.class,
88+
() -> orderByConverter.convert(List.of(orderByExpressionWithoutAlias), requestContext));
89+
}
90+
6091
@ParameterizedTest
6192
@EnumSource(
6293
value = org.hypertrace.entity.query.service.v1.SortOrder.class,

0 commit comments

Comments
 (0)