This is an automated email from the ASF dual-hosted git repository. karan pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push: new d359bf0c31c Preserve column names as-is for unnest queries in the decoupled planner mode. (#17997) d359bf0c31c is described below commit d359bf0c31c224a6e9fcbb765184c35d45e37169 Author: Abhishek Radhakrishnan <abhishek.r...@gmail.com> AuthorDate: Tue May 13 03:17:00 2025 -0700 Preserve column names as-is for unnest queries in the decoupled planner mode. (#17997) Unnest queries in the decoupled planner mode adds a suffix "_null" for some cases. Currently the PlannerResult is based on the built query's output type rather than the planned output type (which shouldn't contain the "_null" suffix). This is the same for "coupled" planner. The planner result is used for populating things in the sql direct statement. The sql row transformer depends on the planner result, so this PR fixes that by aligning with the planned output type. --- .../druid/sql/calcite/planner/QueryHandler.java | 7 +- .../org/apache/druid/sql/http/SqlResourceTest.java | 103 +++++++++++++++++++++ 2 files changed, 106 insertions(+), 4 deletions(-) diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/QueryHandler.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/QueryHandler.java index 0f2f25ef6d3..9e608f7616a 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/QueryHandler.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/QueryHandler.java @@ -540,6 +540,8 @@ public abstract class QueryHandler extends SqlStatementHandler.BaseStatementHand QueryValidations.validateLogicalQueryForDruid(handlerContext.plannerContext(), parameterized); CalcitePlanner planner = handlerContext.planner(); + final RelDataType rowType = prepareResult.getReturnedRowType(); + if (plannerContext.getPlannerConfig() .getNativeQuerySqlPlanningMode() .equals(QueryContexts.NATIVE_QUERY_SQL_PLANNING_MODE_DECOUPLED) @@ -574,7 +576,7 @@ public abstract class QueryHandler extends SqlStatementHandler.BaseStatementHand return planExplanation(possiblyLimitedRoot, newRoot, true); } - return new PlannerResult(resultsSupplier, finalBaseQuery.getOutputRowType()); + return new PlannerResult(resultsSupplier, rowType); } else { final DruidRel<?> druidRel = (DruidRel<?>) planner.transform( CalciteRulesManager.DRUID_CONVENTION_RULES, @@ -591,9 +593,6 @@ public abstract class QueryHandler extends SqlStatementHandler.BaseStatementHand if (explain != null) { return planExplanation(possiblyLimitedRoot, druidRel, true); } else { - // Compute row type. - final RelDataType rowType = prepareResult.getReturnedRowType(); - // sanity check final Set<ResourceAction> readResourceActions = plannerContext.getResourceActions() diff --git a/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java b/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java index 8b767de3b5a..f18873668ea 100644 --- a/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java +++ b/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java @@ -634,6 +634,109 @@ public class SqlResourceTest extends CalciteTestBase ); } + + @Test + public void testPivotRowTypePreservedInDecoupledPlanner() throws Exception + { + final List<Map<String, Object>> rows = doPost( + new SqlQuery( + "SET plannerStrategy='DECOUPLED';" + + " WITH t1 AS (\n" + + " SELECT *\n" + + " FROM (\n" + + " VALUES\n" + + " ('18-19', 'female', 84),\n" + + " ('18-19', 'male', 217),\n" + + " ('20-29', 'female', 321),\n" + + " ('20-29', 'male', 820),\n" + + " ('30-39', 'female', 63),\n" + + " ('30-39', 'male', 449),\n" + + " ('40-49', 'female', 10),\n" + + " ('40-49', 'male', 83),\n" + + " ('50-59', 'female', 2),\n" + + " ('50-59', 'male', 13)\n" + + " ) AS data(Age, Gender, Visitors)\n" + + "),\n" + + "t2 AS (\n" + + " SELECT Age, Gender, CAST(SUM(Visitors) AS double) / (SELECT SUM(Visitors) FROM t1) AS Share\n" + + " FROM t1\n" + + " GROUP BY 1, 2\n" + + ")\n" + + "SELECT *\n" + + "FROM t2\n" + + "PIVOT (MAX(Share) FOR Gender IN ('female' AS Women, 'male' AS Men));", + ResultFormat.OBJECT, + false, + false, + false, + null, + null + ) + ).rhs; + + Assert.assertEquals( + ImmutableList.of( + ImmutableMap.of("Age", "18-19", "Women", 0.040737148399612025, "Men", 0.1052376333656644), + ImmutableMap.of("Age", "20-29", "Women", 0.1556741028128031, "Men", 0.3976721629485936), + ImmutableMap.of("Age", "30-39", "Women", 0.030552861299709022, "Men", 0.2177497575169738), + ImmutableMap.of("Age", "40-49", "Women", 0.004849660523763337, "Men", 0.040252182347235696), + ImmutableMap.of("Age", "50-59", "Women", 0.0009699321047526673, "Men", 0.006304558680892337) + ), + rows + ); + } + + @Test + public void testPivotRowTypePreservedInCoupledPlanner() throws Exception + { + final List<Map<String, Object>> rows = doPost( + new SqlQuery( + "SET plannerStrategy='COUPLED';" + + " WITH t1 AS (\n" + + " SELECT *\n" + + " FROM (\n" + + " VALUES\n" + + " ('18-19', 'female', 84),\n" + + " ('18-19', 'male', 217),\n" + + " ('20-29', 'female', 321),\n" + + " ('20-29', 'male', 820),\n" + + " ('30-39', 'female', 63),\n" + + " ('30-39', 'male', 449),\n" + + " ('40-49', 'female', 10),\n" + + " ('40-49', 'male', 83),\n" + + " ('50-59', 'female', 2),\n" + + " ('50-59', 'male', 13)\n" + + " ) AS data(Age, Gender, Visitors)\n" + + "),\n" + + "t2 AS (\n" + + " SELECT Age, Gender, CAST(SUM(Visitors) AS double) / (SELECT SUM(Visitors) FROM t1) AS Share\n" + + " FROM t1\n" + + " GROUP BY 1, 2\n" + + ")\n" + + "SELECT *\n" + + "FROM t2\n" + + "PIVOT (MAX(Share) FOR Gender IN ('female' AS Women, 'male' AS Men));", + ResultFormat.OBJECT, + false, + false, + false, + null, + null + ) + ).rhs; + + Assert.assertEquals( + ImmutableList.of( + ImmutableMap.of("Age", "18-19", "Women", 0.040737148399612025, "Men", 0.1052376333656644), + ImmutableMap.of("Age", "20-29", "Women", 0.1556741028128031, "Men", 0.3976721629485936), + ImmutableMap.of("Age", "30-39", "Women", 0.030552861299709022, "Men", 0.2177497575169738), + ImmutableMap.of("Age", "40-49", "Women", 0.004849660523763337, "Men", 0.040252182347235696), + ImmutableMap.of("Age", "50-59", "Women", 0.0009699321047526673, "Men", 0.006304558680892337) + ), + rows + ); + } + @Test public void testArrayResultFormat() throws Exception { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@druid.apache.org For additional commands, e-mail: commits-h...@druid.apache.org