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

   `EXPLAIN PLAN FOR <query>` can return a plan for a query that cannot 
actually run. The
   following succeeds against `ColocatedJoinEngineQuickStart`:
   
   ```sql
   EXPLAIN PLAN FOR
   SELECT * FROM userAttributes /*+ tableOptions(partition_function='hashcode', 
partition_key='daysSinceFirstTrip', partition_size='2') */ a
   JOIN userGroups /*+ tableOptions(partition_function='hashcode', 
partition_key='userUUID', partition_size='2') */ g
   ON a.userUUID = g.userUUID
   ```
   
   but running the same query fails with:
   
   ```
   Partition key: daysSinceFirstTrip does not match partition column: userUUID 
for table: userAttributes_OFFLINE
   ```
   
   ## Root cause
   
   `CompiledQuery#explain` renders a plain logical EXPLAIN straight off the 
optimized `RelNode`
   tree and never calls `toDispatchableSubPlan`. Several classes of planning 
error are only raised
   further down that path:
   
   * `PinotLogicalQueryPlanner#makePlan` (`RelNode` -> `PlanNode` conversion), 
e.g. lookup-join
     shape validation and `ArrayToMv` validation.
   * `WorkerManager` worker assignment, e.g. `checkPartitionInfoMap`, which is 
where a
     `tableOptions` partition hint is compared against the table's real 
partitioning.
   
   So the logical EXPLAIN reports a plan the engine would refuse to execute. 
The other two explain
   branches (`EXPLAIN IMPLEMENTATION PLAN`, and `EXPLAIN PLAN WITH 
IMPLEMENTATION` when
   `explainAskingServers` is on) already build the dispatchable subplan and 
therefore already fail
   correctly — this only affects the default logical EXPLAIN.
   
   ## Fix
   
   Build the dispatchable subplan in the logical branch too, and keep rendering 
the logical plan.
   Parity becomes structural instead of a list of checks that has to be kept in 
sync, and all three
   explain branches now go through the same pipeline.
   
   ## This was not a single bad hint
   
   `ResourceBasedQueryPlansTest#testQueryExplainPlansWithExceptions` was 
calling `explainQuery(query)`
   **and then** `planQuery(query minus the EXPLAIN prefix)` inside one try 
block, so its
   `expectedException` fixtures were being satisfied by the second call. That 
made the existing
   fixtures look like EXPLAIN coverage when they were really execution coverage.
   
   Dropping that second call turns the fixtures into genuine EXPLAIN 
assertions. With this fix all
   590 cases in that suite pass; without it 9 fail, spanning three unrelated 
causes:
   
   * 6 x partition-hint mismatch (`Partition key: ... does not match partition 
column: ...`,
     `Partition size mismatch`, `Partition function mismatch`, `Failed to find 
table partition info`)
   * 2 x `'ArrayToMv' is not supported`
   * 1 x `Right input for lookup join must be an identifier`
   
   ## Behavior change
   
   EXPLAIN now surfaces any planning error that execution would hit, including 
ones that depend on
   live routing state (for example a table whose partitions have no fully 
replicated server right
   now). This is the intended semantics — if the query cannot run, EXPLAIN 
should say so rather than
   print a plan — but it does mean EXPLAIN can start failing where it 
previously returned a plan.
   
   ## Tests
   
   * `ResourceBasedQueryPlansTest`: removed the `planQuery` call from the 
exception path, so the 34
     existing `expectedException` fixtures now actually assert on EXPLAIN. 9 of 
them are regression
     coverage for this fix.
   * `QueryCompilationTest#testJoinPushTransitivePredicateLookupJoin` was 
asserting a plan for a
     query that cannot execute: with `SELECT *` the lookup join's right input 
is a bare table scan,
     and `RelToPlanNodeConverter#convertLogicalJoin` requires an 
identifier-only `Project` over a
     `TableScan`. Switched to selecting explicit columns, which is the shape 
every other lookup-join
     fixture uses. The test still checks what it was written to check — the 
transitive predicate is
     pushed only to the left side under the lookup hint.
   


-- 
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