Details
-
Bug
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
1.18.0
-
None
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:
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); }
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:
@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")); }
Attachments
Attachments
Issue Links
- links to