Make Unnest work with nullif operator (#14993)

This is due to the recursive filter creation in unnest storage adapter not performing correctly in case of an empty children. This PR addresses the issue
This commit is contained in:
Soumyava 2023-09-14 21:24:14 -07:00 committed by GitHub
parent 3ae5e97801
commit 279b3818f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 2 deletions

View File

@ -478,13 +478,16 @@ public class UnnestStorageAdapter implements StorageAdapter
for (Filter filter : queryFilter.getFilters()) { for (Filter filter : queryFilter.getFilters()) {
if (filter.getRequiredColumns().contains(outputColumnName)) { if (filter.getRequiredColumns().contains(outputColumnName)) {
if (filter instanceof AndFilter) { if (filter instanceof AndFilter) {
preFilterList.add(new AndFilter(recursiveRewriteOnUnnestFilters( List<Filter> andChildFilters = recursiveRewriteOnUnnestFilters(
(BooleanFilter) filter, (BooleanFilter) filter,
inputColumn, inputColumn,
inputColumnCapabilites, inputColumnCapabilites,
filterSplitter, filterSplitter,
isTopLevelAndFilter isTopLevelAndFilter
))); );
if (!andChildFilters.isEmpty()) {
preFilterList.add(new AndFilter(andChildFilters));
}
} else if (filter instanceof OrFilter) { } else if (filter instanceof OrFilter) {
// in case of Or Fiters, we set isTopLevelAndFilter to false that prevents pushing down any child filters to base // in case of Or Fiters, we set isTopLevelAndFilter to false that prevents pushing down any child filters to base
List<Filter> orChildFilters = recursiveRewriteOnUnnestFilters( List<Filter> orChildFilters = recursiveRewriteOnUnnestFilters(

View File

@ -4807,4 +4807,52 @@ public class CalciteArraysQueryTest extends BaseCalciteQueryTest
) )
); );
} }
@Test
public void testUnnestVirtualWithColumnsAndNullIf()
{
skipVectorize();
cannotVectorize();
testQuery(
"select c,m2 from druid.foo, unnest(ARRAY[\"m1\", \"m2\"]) as u(c) where NULLIF(c,m2) IS NULL",
QUERY_CONTEXT_UNNEST,
ImmutableList.of(
Druids.newScanQueryBuilder()
.dataSource(UnnestDataSource.create(
new TableDataSource(CalciteTests.DATASOURCE1),
expressionVirtualColumn("j0.unnest", "array(\"m1\",\"m2\")", ColumnType.FLOAT_ARRAY),
null
))
.intervals(querySegmentSpec(Filtration.eternity()))
.resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST)
.filters(
useDefault ? expressionFilter("(\"j0.unnest\" == \"m2\")") :
or(
expressionFilter("(\"j0.unnest\" == \"m2\")"),
and(
isNull("j0.unnest"),
not(expressionFilter("(\"j0.unnest\" == \"m2\")"))
)
))
.legacy(false)
.context(QUERY_CONTEXT_UNNEST)
.columns(ImmutableList.of("j0.unnest", "m2"))
.build()
),
ImmutableList.of(
new Object[]{1.0f, 1.0D},
new Object[]{1.0f, 1.0D},
new Object[]{2.0f, 2.0D},
new Object[]{2.0f, 2.0D},
new Object[]{3.0f, 3.0D},
new Object[]{3.0f, 3.0D},
new Object[]{4.0f, 4.0D},
new Object[]{4.0f, 4.0D},
new Object[]{5.0f, 5.0D},
new Object[]{5.0f, 5.0D},
new Object[]{6.0f, 6.0D},
new Object[]{6.0f, 6.0D}
)
);
}
} }