Skip to content

Commit ef14884

Browse files
committed
Added support for ANY filters when building deduplicate aggregations
1 parent e9db00a commit ef14884

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

src/main/java/io/cdap/plugin/gcp/bigquery/sqlengine/builder/BigQueryBaseSQLBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public abstract class BigQueryBaseSQLBuilder {
5050
public static final String ROW_NUMBER_PARTITION_COLUMN =
5151
"ROW_NUMBER() OVER ( PARTITION BY %s ORDER BY %s ) AS `%s`";
5252
public static final String NULLS_LAST = "NULLS LAST";
53+
public static final String IFNULL_FUNCTION = "IFNULL";
54+
public static final String ZERO = "0";
55+
public static final String ONE = "1";
5356

5457
/**
5558
* Builds SQL statement

src/main/java/io/cdap/plugin/gcp/bigquery/sqlengine/builder/BigQueryDeduplicateSQLBuilder.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,27 @@ protected String getOrderByFields(List<DeduplicateAggregationDefinition.FilterEx
134134
* @return Order by SQL expression
135135
*/
136136
protected String getOrderByField(DeduplicateAggregationDefinition.FilterExpression filterExpression) {
137-
String order;
138-
139-
// MAX of a value means ORDER DESCENDING and selecting the first result.
140-
// MIN of a value means ORDER ASCENDING and selecting the first result.
141-
if (filterExpression.getFilterFunction() == DeduplicateAggregationDefinition.FilterFunction.MAX) {
142-
order = ORDER_DESC;
143-
} else {
144-
order = ORDER_ASC;
137+
String exp = ((SQLExpression) filterExpression.getExpression()).extract();
138+
139+
switch (filterExpression.getFilterFunction()) {
140+
case MIN:
141+
// MIN of a value means ORDER ASCENDING and selecting the first result.
142+
// ...[ORDER BY] exp ASC NULLS LAST
143+
return exp + SPACE + ORDER_ASC + SPACE + NULLS_LAST;
144+
case MAX:
145+
// MAX of a value means ORDER DESCENDING and selecting the first result.
146+
// ...[ORDER BY] exp DESC NULLS LAST
147+
return exp + SPACE + ORDER_DESC + SPACE + NULLS_LAST;
148+
case ANY_NULLS_FIRST:
149+
// ANY_NULLS_FIRST means order with null values first and pick the first.
150+
// ...[ORDER BY] IFNULL(exp , 0 , 1) ASC
151+
return IFNULL_FUNCTION + OPEN_GROUP + exp + COMMA + ZERO + COMMA + ONE + CLOSE_GROUP + SPACE + ORDER_ASC;
152+
case ANY_NULLS_LAST:
153+
default:
154+
// ANY_NULLS_LAST means order with null values first and pick the first.
155+
// ...[ORDER BY] IFNULL(exp , 0 , 1) DESC
156+
return IFNULL_FUNCTION + OPEN_GROUP + exp + COMMA + ZERO + COMMA + ONE + CLOSE_GROUP + SPACE + ORDER_DESC;
145157
}
146-
147-
// some_field ASC/DESC
148-
return ((SQLExpression) filterExpression.getExpression()).extract() + SPACE + order + SPACE + NULLS_LAST;
149158
}
150159

151160
}

src/test/java/io/cdap/plugin/gcp/bigquery/sqlengine/builder/BigQueryDeduplicateSQLBuilderTest.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,14 @@ public void testGetSelectedFields() {
111111
+ "d AS d , "
112112
+ "e AS e , "
113113
+ "f AS f , "
114-
+ "ROW_NUMBER() OVER ( PARTITION BY c , d , e ORDER BY e DESC NULLS LAST , f ASC NULLS LAST ) AS" +
115-
" `the_row_number`", helper.getSelectedFields(def));
114+
+ "ROW_NUMBER() OVER ( PARTITION BY c , d , e ORDER BY e DESC NULLS LAST , f ASC NULLS LAST ) AS" +
115+
" `the_row_number`", helper.getSelectedFields(def));
116116
}
117117

118118
@Test
119119
public void testGetRowNumColumn() {
120120
Assert.assertEquals("ROW_NUMBER() OVER ( PARTITION BY c , d , e ORDER BY e DESC NULLS LAST , " +
121-
"f ASC NULLS LAST ) AS `the_row_number`", helper.getRowNumColumn(def));
121+
"f ASC NULLS LAST ) AS `the_row_number`", helper.getRowNumColumn(def));
122122
}
123123

124124
@Test
@@ -139,9 +139,19 @@ public void testGetOrderByField() {
139139
DeduplicateAggregationDefinition.FilterExpression minField2 =
140140
new DeduplicateAggregationDefinition.FilterExpression(factory.compile("field2"),
141141
DeduplicateAggregationDefinition.FilterFunction.MIN);
142+
DeduplicateAggregationDefinition.FilterExpression minField3 =
143+
new DeduplicateAggregationDefinition
144+
.FilterExpression(factory.compile("field3"),
145+
DeduplicateAggregationDefinition.FilterFunction.ANY_NULLS_FIRST);
146+
DeduplicateAggregationDefinition.FilterExpression minField4 =
147+
new DeduplicateAggregationDefinition
148+
.FilterExpression(factory.compile("field4"),
149+
DeduplicateAggregationDefinition.FilterFunction.ANY_NULLS_LAST);
142150

143151
Assert.assertEquals("field1 DESC NULLS LAST", helper.getOrderByField(maxField1));
144152
Assert.assertEquals("field2 ASC NULLS LAST", helper.getOrderByField(minField2));
153+
Assert.assertEquals("IFNULL(field3 , 0 , 1) ASC", helper.getOrderByField(minField3));
154+
Assert.assertEquals("IFNULL(field4 , 0 , 1) DESC", helper.getOrderByField(minField4));
145155
}
146156

147157

0 commit comments

Comments
 (0)