yashmayya opened a new pull request, #19768:
URL: https://github.com/apache/pinot/pull/19768

   Depends on #19766. This branch includes the commit of #19766, so review only 
the last commit.
   
   This PR fixes the `CAST` item in the "Limits" section of #19766.
   
   ## The bug
   
   With `explainAskingServers` (or 
`pinot.query.multistage.explain.include.segment.plan`), 
`PlanNodeToRelConverter` converts the plan nodes from the servers back to 
Calcite nodes.
   
   A plan node holds `CAST(x AS T)` as a `CAST` call with two operands: `x`, 
and a `STRING` literal with the name of `T` (see 
`RexExpressionUtils.handleCast()`). `toRexCall()` gives both operands to the 
Calcite `CAST` operator. Calcite then uses the type of the second operand as 
the type of the cast.
   
   For example, take this query with the default planner rules:
   
   ```sql
   SELECT Carrier, SUM(v) FROM (SELECT /*+ 
aggOptions(is_partitioned_by_group_by_keys='true') */ Carrier, Origin, 
AVG(ArrDelay) AS v FROM mytable GROUP BY Carrier, Origin) GROUP BY Carrier
   ```
   
   EXPLAIN shows:
   
   ```
   LogicalProject(Carrier=[$0], $f1=[DIVIDE(CAST($2, 'DOUBLE'):CHAR(6) NOT 
NULL, $3)])
   ```
   
   Before #19766, the nodes with this `CAST` usually showed as `Unknown`, so 
this bug was hidden.
   
   ## The fix
   
   In `toRexCall()`, create `CAST` with `RexBuilder.makeCast()` from the first 
operand. Use the type of the call as the target type, with the nullability of 
the operand. This is the inverse of `handleCast()`. EXPLAIN now shows:
   
   ```
   LogicalProject(Carrier=[$0], $f1=[DIVIDE(CAST($2):DOUBLE NOT NULL, $3)])
   ```
   
   Only the EXPLAIN output changes. Query execution does not use this 
conversion.
   
   ## Testing
   
   - `RexExpressionUtilsTest.testCastRoundTrip` converts a `CAST` call to a 
Calcite node and back. It also checks that a nullable operand gives a nullable 
cast. Without this change, the test fails in `handleCast()`, which expects one 
operand.
   - I ran the query above in a temporary integration test with 
`pinot.query.multistage.explain.include.segment.plan=true` and the default 
planner rules. EXPLAIN shows `DIVIDE(CAST($2):DOUBLE NOT NULL, $3)` and no 
`Unknown` nodes.
   - All 2659 `pinot-query-planner` tests pass. `spotless`, `checkstyle` and 
`license` are clean.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to