[ 
https://issues.apache.org/jira/browse/CALCITE-7792?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Sean Broeder updated CALCITE-7792:
----------------------------------
    Summary: Failed namespace validation leaves rowType null and causes stack 
overflow in getRowType()  (was: AbstractNamespace.validate() sets status VALID 
even after validateImpl() throws)

> Failed namespace validation leaves rowType null and causes stack overflow in 
> getRowType()
> -----------------------------------------------------------------------------------------
>
>                 Key: CALCITE-7792
>                 URL: https://issues.apache.org/jira/browse/CALCITE-7792
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.42.0
>            Reporter: Sean Broeder
>            Assignee: Sean Broeder
>            Priority: Major
>
> AbstractNamespace.validate()'s finally block sets status = VALID even when 
> validateImpl() throws, leaving rowType null. A subsequent getRowType() call 
> on that same namespace then recurses forever rather than resurfacing the 
> original error.  It sees rowType == null and calls validateNamespace(), which 
> calls namespace.validate(...) and since status is already VALID, it calls 
> namespace.getType() -> getRowType() again, ending in a StackOverflowError.
> example:
> {code:java}
> select * from (select bad_col from emp) as t
> {code}
> Validating this throws "Column 'BAD_COL' not found in any table" the first 
> time, as expected. But a second, independent getRowType() call on the inner 
> SELECT's namespace then throws StackOverflowError instead of re-surfacing 
> that error.
> Reachability: this isn't triggered by ordinary correlated SQL through a 
> single top-level validate() call — I checked a CTE referenced twice via 
> correlated EXISTS clauses and two independently-correlated subqueries over 
> the same derived-table. Both surface the clean underlying error, not this 
> bug. Calcite's own internal re-entrant validate()/getRowType() calls only 
> land on namespaces that haven't failed yet, and a genuine failure aborts the 
> whole top-level validate() call before anything gets a second look at that 
> same namespace.
> The bug needs something that catches an exception from probing a namespace 
> and keeps going.  In my case, this is a validator extension that 
> speculatively resolves an identifier against several candidate scopes and 
> treats a resolution failure as "not a match" rather than a hard error.  An 
> external caller that revalidates the same parsed query or asks for a 
> namespace's type again after an earlier validation attempt on it would also 
> hit the issue.
> This problem can be mitigated if status is set conditionally in the finally 
> block and I see no impact on standard Calcite users in doing so, so I am 
> hoping this is agreeable.
> {code:java}
> status = succeeded ? SqlValidatorImpl.Status.VALID : 
> SqlValidatorImpl.Status.UNVALIDATED;
> {code}



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to