[
https://issues.apache.org/jira/browse/CALCITE-2894?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ruben Quesada Lopez updated CALCITE-2894:
-----------------------------------------
Description:
{{RelMdPercentageOriginalRows}} methods use several times {{double}} variables
to store the result of {{getPercentageOriginalRows}}. However, this method
returns an object {{Double}}, as {{RelMetadataQuery#getPercentageOriginalRows}}
javadoc says: "return estimated percentage (between 0.0 and 1.0), *or null if
no reliable estimate can be determined*".
Therefore, {{null}} can (and will) be returned in some cases, leading to
NullPointerException, for example here:
{code:java}
public Double getPercentageOriginalRows(Union rel, RelMetadataQuery mq) {
double numerator = 0.0;
double denominator = 0.0;
for (RelNode input : rel.getInputs()) {
double rowCount = mq.getRowCount(input);
double percentage = mq.getPercentageOriginalRows(input); // !!!
NullPointerException
if (percentage != 0.0) {
denominator += rowCount / percentage;
numerator += rowCount;
}
}
return quotientForPercentage(numerator, denominator);
}
{code}
In my case, I arrived to this situation by explaining a plan (including all
attributes) that contained a SemiJoin, with an Union inside, with a Correlate
inside:
{code:java}
@Test public void testExplainAllAttributesSemiJoinUnionCorrelate() {
CalciteAssert.that()
.with(CalciteConnectionProperty.LEX, Lex.JAVA)
.with(CalciteConnectionProperty.FORCE_DECORRELATE, false)
.withSchema("s", new ReflectiveSchema(new JdbcTest.HrSchema()))
.query(
"select deptno, name from depts where deptno in (\n"
+ " select e.deptno from emps e where exists
(select 1 from depts d where d.deptno=e.deptno)\n"
+ " union select e.deptno from emps e where
e.salary > 10000) ")
.explainMatches("including all attributes ",
CalciteAssert.checkResultContains("EnumerableSemiJoin"));
}
{code}
was:
{{RelMdPercentageOriginalRows}} methods use several times {{double}} variables
to store the result of {{getPercentageOriginalRows}}. However, this method
returns an object {{Double}}, as {{RelMetadataQuery#getPercentageOriginalRows}}
javadoc says: "return estimated percentage (between 0.0 and 1.0), *or null if
no reliable estimate can be determined*".
Therefore, {{null}} can (and will) be returned in some cases, leading to
NullPointerException.
In my case, I arrived to the situation by explaining a plan (including all
attributes) that contained a SemiJoin, with an Union inside, with a Correlate
inside:
{code:java}
@Test public void testExplainAllAttributesSemiJoinUnionCorrelate() {
CalciteAssert.that()
.with(CalciteConnectionProperty.LEX, Lex.JAVA)
.with(CalciteConnectionProperty.FORCE_DECORRELATE, false)
.withSchema("s", new ReflectiveSchema(new JdbcTest.HrSchema()))
.query(
"select deptno, name from depts where deptno in (\n"
+ " select e.deptno from emps e where exists
(select 1 from depts d where d.deptno=e.deptno)\n"
+ " union select e.deptno from emps e where
e.salary > 10000) ")
.explainMatches("including all attributes ",
CalciteAssert.checkResultContains("EnumerableSemiJoin"));
}
{code}
> NullPointerException thrown by RelMdPercentageOriginalRows when explaining
> plan with all attributes
> ---------------------------------------------------------------------------------------------------
>
> Key: CALCITE-2894
> URL: https://issues.apache.org/jira/browse/CALCITE-2894
> Project: Calcite
> Issue Type: Bug
> Affects Versions: 1.18.0
> Reporter: Ruben Quesada Lopez
> Assignee: Ruben Quesada Lopez
> Priority: Minor
>
> {{RelMdPercentageOriginalRows}} methods use several times {{double}}
> variables to store the result of {{getPercentageOriginalRows}}. However, this
> method returns an object {{Double}}, as
> {{RelMetadataQuery#getPercentageOriginalRows}} javadoc says: "return
> estimated percentage (between 0.0 and 1.0), *or null if no reliable estimate
> can be determined*".
> Therefore, {{null}} can (and will) be returned in some cases, leading to
> NullPointerException, for example here:
> {code:java}
> public Double getPercentageOriginalRows(Union rel, RelMetadataQuery mq) {
> double numerator = 0.0;
> double denominator = 0.0;
> for (RelNode input : rel.getInputs()) {
> double rowCount = mq.getRowCount(input);
> double percentage = mq.getPercentageOriginalRows(input); // !!!
> NullPointerException
> if (percentage != 0.0) {
> denominator += rowCount / percentage;
> numerator += rowCount;
> }
> }
> return quotientForPercentage(numerator, denominator);
> }
> {code}
> In my case, I arrived to this situation by explaining a plan (including all
> attributes) that contained a SemiJoin, with an Union inside, with a Correlate
> inside:
> {code:java}
> @Test public void testExplainAllAttributesSemiJoinUnionCorrelate() {
> CalciteAssert.that()
> .with(CalciteConnectionProperty.LEX, Lex.JAVA)
> .with(CalciteConnectionProperty.FORCE_DECORRELATE, false)
> .withSchema("s", new ReflectiveSchema(new JdbcTest.HrSchema()))
> .query(
> "select deptno, name from depts where deptno in (\n"
> + " select e.deptno from emps e where exists
> (select 1 from depts d where d.deptno=e.deptno)\n"
> + " union select e.deptno from emps e where
> e.salary > 10000) ")
> .explainMatches("including all attributes ",
> CalciteAssert.checkResultContains("EnumerableSemiJoin"));
> }
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)