diff --git a/processing/src/main/java/org/apache/druid/segment/UnnestStorageAdapter.java b/processing/src/main/java/org/apache/druid/segment/UnnestStorageAdapter.java index 83694d9618d5..02f8c0064aa2 100644 --- a/processing/src/main/java/org/apache/druid/segment/UnnestStorageAdapter.java +++ b/processing/src/main/java/org/apache/druid/segment/UnnestStorageAdapter.java @@ -478,13 +478,16 @@ private List recursiveRewriteOnUnnestFilters( for (Filter filter : queryFilter.getFilters()) { if (filter.getRequiredColumns().contains(outputColumnName)) { if (filter instanceof AndFilter) { - preFilterList.add(new AndFilter(recursiveRewriteOnUnnestFilters( + List andChildFilters = recursiveRewriteOnUnnestFilters( (BooleanFilter) filter, inputColumn, inputColumnCapabilites, filterSplitter, isTopLevelAndFilter - ))); + ); + if (!andChildFilters.isEmpty()) { + preFilterList.add(new AndFilter(andChildFilters)); + } } else if (filter instanceof OrFilter) { // in case of Or Fiters, we set isTopLevelAndFilter to false that prevents pushing down any child filters to base List orChildFilters = recursiveRewriteOnUnnestFilters( diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java index 4842044892dc..df4e9b62cc9e 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteArraysQueryTest.java @@ -4807,4 +4807,52 @@ public void testUnnestWithGroupByHavingWithWhereOnUnnestCol() ) ); } + + @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} + ) + ); + } }