[
https://issues.apache.org/jira/browse/CALCITE-4414?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
ASF GitHub Bot updated CALCITE-4414:
------------------------------------
Labels: pull-request-available (was: )
> 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: 10m
> 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)