[ 
https://issues.apache.org/jira/browse/CALCITE-4414?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17238126#comment-17238126
 ] 

Ruben Q L commented on CALCITE-4414:
------------------------------------

[~julianhyde], if I am not mistaken, you implemented 
RelMdSelectivity#getSelectivity for Project; maybe you could take a look at 
this patch involving Calc, please?

> RelMdSelectivity#getSelectivity for Calc can propagate a predicate with wrong 
> references
> ----------------------------------------------------------------------------------------
>
>                 Key: CALCITE-4414
>                 URL: https://issues.apache.org/jira/browse/CALCITE-4414
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>            Reporter: Ruben Q L
>            Assignee: Ruben Q L
>            Priority: Major
>              Labels: pull-request-available
>             Fix For: 1.27.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> {{RelMdSelectivity#getSelectivity(Calc rel, RelMetadataQuery mq, RexNode 
> predicate)}} method:
> {code}
>   public Double getSelectivity(Calc rel, RelMetadataQuery mq, RexNode 
> predicate) {
>     final RexProgram rexProgram = rel.getProgram();
>     final RexLocalRef programCondition = rexProgram.getCondition();
>     if (programCondition == null) {
>       return getSelectivity(rel.getInput(), mq, predicate); // [2]
>     } else {
>       // [1]
>       return mq.getSelectivity(rel.getInput(),
>           RelMdUtil.minusPreds(
>               rel.getCluster().getRexBuilder(),
>               predicate,
>               rexProgram.expandLocalRef(programCondition)));
>     }
>   }
> {code}
> currently passes down the predicate to its input [1] without considering any 
> possible translation, since the predicate might include expressions generated 
> by the Calc's projections; hence when the Calc's input analyzes the 
> predicate, it can end up trying to access fields that do not exist on its 
> rowType.
> This can lead to unforeseeable consequences, like the test attached to the 
> first comment, where after {{RelMdSelectivity#getSelectivity(Calc)}} we reach 
> {{RelMdSelectivity#getSelectivity(Union)}} and this method ends up in an 
> {{ArrayIndexOutOfBoundsException}} because it tries to access a field ($1) 
> that does not exists on its rowType (which only has $0). This $1 is actually 
> projected by the Calc which is on top of the Union.
> Note I: in a similar situation, RelM uses{{ RelOptUtil.pushPastProject}} 
> (which "Converts an expression that is based on the output fields of a 
> Project to an equivalent expression on the Project's input fields.") to 
> convert the predicate before passing it to the Project's input.
> Note II: in the code snipped above that in our test example the issue only 
> happens in line [1], and not in [2] because the "if" block calls 
> {{getSelectivity}} instead of {{mq.getSelectivity}}, although I find this a 
> bit questionable and maybe {{mq.getSelectivity}} should be called here as 
> well.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to