From 261f54dc040d9e95846c9d091b8dcb258ccc6c27 Mon Sep 17 00:00:00 2001 From: Soumyava <93540295+somu-imply@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:26:50 -0700 Subject: [PATCH] coalesce on unnest row mismatch fix (#15019) * coalesce on unnest row mismatch fix * new example with coalesce over unnest with nested array columns * New example with change in order which triggers the nvl * new test plan update for useDefault=true --- .../rule/DruidCorrelateUnnestRule.java | 1 + .../calcite/CalciteNestedDataQueryTest.java | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rule/DruidCorrelateUnnestRule.java b/sql/src/main/java/org/apache/druid/sql/calcite/rule/DruidCorrelateUnnestRule.java index be025ef5130c..a83bb394826f 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/rule/DruidCorrelateUnnestRule.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/rule/DruidCorrelateUnnestRule.java @@ -174,6 +174,7 @@ public void onMatch(RelOptRuleCall call) ) ); + relBuilder.convert(correlate.getRowType(), false); final RelNode build = relBuilder.build(); call.transformTo(build); } diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java index 406f94b46435..d440a6bb7182 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteNestedDataQueryTest.java @@ -6308,4 +6308,96 @@ public void testFilterJsonIsNull() ); } + + @Test + public void testCoalesceOnNestedColumns() + { + // jo.unnest is first entry in coalesce + // so Calcite removes the coalesce to be used here + testQuery( + "select coalesce(c,long) as col " + + " from druid.all_auto, unnest(json_value(arrayNestedLong, '$[1]' returning bigint array)) as u(c) ", + ImmutableList.of( + Druids.newScanQueryBuilder() + .dataSource(UnnestDataSource.create( + new TableDataSource(DATA_SOURCE_ALL), + new NestedFieldVirtualColumn("arrayNestedLong", "$[1]", "j0.unnest", ColumnType.LONG_ARRAY), + null + )) + .intervals(querySegmentSpec(Filtration.eternity())) + .columns("j0.unnest") + .resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST) + .legacy(false) + .context(QUERY_CONTEXT_DEFAULT) + .build() + ), + ImmutableList.of( + new Object[]{null}, + new Object[]{3L}, + new Object[]{4L}, + new Object[]{3L}, + new Object[]{4L}, + new Object[]{1L}, + new Object[]{2L}, + new Object[]{null} + ), + RowSignature.builder() + .add("col", ColumnType.LONG) + .build() + ); + } + + @Test + public void testCoalesceOnNestedColumnsLater() + { + // the first column in coalesce comes from the table + // so a virtual expression is present for the coalesce + testQuery( + "select coalesce(long,c) as col " + + " from druid.all_auto, unnest(json_value(arrayNestedLong, '$[1]' returning bigint array)) as u(c) ", + useDefault ? + ImmutableList.of( + Druids.newScanQueryBuilder() + .dataSource(UnnestDataSource.create( + new TableDataSource(DATA_SOURCE_ALL), + new NestedFieldVirtualColumn("arrayNestedLong", "$[1]", "j0.unnest", ColumnType.LONG_ARRAY), + null + )) + .intervals(querySegmentSpec(Filtration.eternity())) + .columns("long") + .resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST) + .legacy(false) + .context(QUERY_CONTEXT_DEFAULT) + .build() + ) : + ImmutableList.of( + Druids.newScanQueryBuilder() + .dataSource(UnnestDataSource.create( + new TableDataSource(DATA_SOURCE_ALL), + new NestedFieldVirtualColumn("arrayNestedLong", "$[1]", "j0.unnest", ColumnType.LONG_ARRAY), + null + )) + .intervals(querySegmentSpec(Filtration.eternity())) + .virtualColumns(expressionVirtualColumn("v0", "nvl(\"long\",\"j0.unnest\")", ColumnType.LONG)) + .columns("v0") + .resultFormat(ScanQuery.ResultFormat.RESULT_FORMAT_COMPACTED_LIST) + .legacy(false) + .context(QUERY_CONTEXT_DEFAULT) + .build() + ), + ImmutableList.of( + new Object[]{2L}, + new Object[]{1L}, + new Object[]{1L}, + new Object[]{4L}, + new Object[]{4L}, + new Object[]{5L}, + new Object[]{5L}, + new Object[]{5L} + ), + RowSignature.builder() + .add("col", ColumnType.LONG) + .build() + ); + } }