-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL: Support GROUP BY and ORDER BY for NULL types. #16252
base: master
Are you sure you want to change the base?
Changes from all commits
3865fed
9030797
231a3dc
3ae380b
9e368f9
685668c
10b50dd
139a878
e69b12f
725d2e9
216cc74
7fc2b77
43942e9
694b089
46b2c3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6779,6 +6779,114 @@ public void testCountStarWithTimeInIntervalFilterLosAngeles() | |||||||||||
); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@Test | ||||||||||||
public void testGroupByNullType() | ||||||||||||
{ | ||||||||||||
// Cannot vectorize due to null constant expression. | ||||||||||||
cannotVectorize(); | ||||||||||||
testQuery( | ||||||||||||
"SELECT NULL as nullcol, COUNT(*) FROM druid.foo GROUP BY 1", | ||||||||||||
ImmutableList.of( | ||||||||||||
new GroupByQuery.Builder() | ||||||||||||
.setDataSource(CalciteTests.DATASOURCE1) | ||||||||||||
.setInterval(querySegmentSpec(Filtration.eternity())) | ||||||||||||
.setGranularity(Granularities.ALL) | ||||||||||||
.setVirtualColumns(expressionVirtualColumn("v0", "null", ColumnType.STRING)) | ||||||||||||
.setDimensions(dimensions(new DefaultDimensionSpec("v0", "d0", ColumnType.STRING))) | ||||||||||||
.setAggregatorSpecs(aggregators(new CountAggregatorFactory("a0"))) | ||||||||||||
.setContext(QUERY_CONTEXT_DEFAULT) | ||||||||||||
.build() | ||||||||||||
), | ||||||||||||
ImmutableList.of( | ||||||||||||
new Object[]{null, 6L} | ||||||||||||
) | ||||||||||||
); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@Test | ||||||||||||
public void testOrderByNullType() | ||||||||||||
Comment on lines
+6806
to
+6807
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instead of overriding+disabling the testcase; it can be marked as unsupported with:
Suggested change
this has the benefit that it will be verified that it still fails and could also be located based on the type of failure it have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, thanks, cool idea! It is supported for the basic planner, so I kept the override in |
||||||||||||
{ | ||||||||||||
testQuery( | ||||||||||||
// Order on subquery, since the native engine doesn't currently support ordering when selecting directly | ||||||||||||
// from a table. | ||||||||||||
"SELECT dim1, NULL as nullcol FROM (SELECT DISTINCT dim1 FROM druid.foo LIMIT 1) ORDER BY 2", | ||||||||||||
ImmutableList.of( | ||||||||||||
WindowOperatorQueryBuilder | ||||||||||||
.builder() | ||||||||||||
.setDataSource( | ||||||||||||
new TopNQueryBuilder() | ||||||||||||
.dataSource(CalciteTests.DATASOURCE1) | ||||||||||||
.intervals(querySegmentSpec(Filtration.eternity())) | ||||||||||||
.dimension(new DefaultDimensionSpec("dim1", "d0", ColumnType.STRING)) | ||||||||||||
.threshold(1) | ||||||||||||
.metric(new DimensionTopNMetricSpec(null, StringComparators.LEXICOGRAPHIC)) | ||||||||||||
.postAggregators(expressionPostAgg("s0", "null", ColumnType.STRING)) | ||||||||||||
.context(QUERY_CONTEXT_DEFAULT) | ||||||||||||
.build() | ||||||||||||
) | ||||||||||||
.setSignature( | ||||||||||||
RowSignature.builder() | ||||||||||||
.add("d0", ColumnType.STRING) | ||||||||||||
.add("s0", ColumnType.STRING) | ||||||||||||
.build() | ||||||||||||
) | ||||||||||||
.setOperators( | ||||||||||||
OperatorFactoryBuilders.naiveSortOperator("s0", ColumnWithDirection.Direction.ASC) | ||||||||||||
) | ||||||||||||
.setLeafOperators( | ||||||||||||
OperatorFactoryBuilders | ||||||||||||
.scanOperatorFactoryBuilder() | ||||||||||||
.setOffsetLimit(0, Long.MAX_VALUE) | ||||||||||||
.setProjectedColumns("d0", "s0") | ||||||||||||
.build() | ||||||||||||
) | ||||||||||||
.build() | ||||||||||||
), | ||||||||||||
ImmutableList.of( | ||||||||||||
new Object[]{"", null} | ||||||||||||
) | ||||||||||||
); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@Test | ||||||||||||
public void testGroupByOrderByNullType() | ||||||||||||
{ | ||||||||||||
// Cannot vectorize due to null constant expression. | ||||||||||||
cannotVectorize(); | ||||||||||||
|
||||||||||||
testQuery( | ||||||||||||
"SELECT NULL as nullcol, COUNT(*) FROM druid.foo GROUP BY 1 ORDER BY 1", | ||||||||||||
ImmutableList.of( | ||||||||||||
new GroupByQuery.Builder() | ||||||||||||
.setDataSource(CalciteTests.DATASOURCE1) | ||||||||||||
.setInterval(querySegmentSpec(Filtration.eternity())) | ||||||||||||
.setGranularity(Granularities.ALL) | ||||||||||||
.setVirtualColumns(expressionVirtualColumn("v0", "null", ColumnType.STRING)) | ||||||||||||
.setDimensions(dimensions(new DefaultDimensionSpec("v0", "d0", ColumnType.STRING))) | ||||||||||||
.setAggregatorSpecs(aggregators(new CountAggregatorFactory("a0"))) | ||||||||||||
.setLimitSpec( | ||||||||||||
queryFramework().engine().featureAvailable(EngineFeature.GROUPBY_IMPLICITLY_SORTS) | ||||||||||||
? NoopLimitSpec.instance() | ||||||||||||
: new DefaultLimitSpec( | ||||||||||||
ImmutableList.of( | ||||||||||||
new OrderByColumnSpec( | ||||||||||||
"d0", | ||||||||||||
Direction.ASCENDING, | ||||||||||||
StringComparators.NATURAL | ||||||||||||
) | ||||||||||||
), | ||||||||||||
Integer.MAX_VALUE | ||||||||||||
) | ||||||||||||
) | ||||||||||||
.setContext(QUERY_CONTEXT_DEFAULT) | ||||||||||||
.build() | ||||||||||||
), | ||||||||||||
ImmutableList.of( | ||||||||||||
new Object[]{null, 6L} | ||||||||||||
) | ||||||||||||
); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@Test | ||||||||||||
public void testCountStarWithTimeInIntervalFilterInvalidInterval() | ||||||||||||
{ | ||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a new columnType called null just like the relDataType : SqlTypeName.null
In that case, we can push this logic inside getStringComparatorsForValueType() and remove this custom handling ?
thoughts ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ColumnType
is meant to represent types that the native query engine can store and process. We don't really have a pure-NULL
type there, so adding one may have larger consequences that I did not want to run into in this patch. I thought it would be better to keep the changes to the SQL layer.