Darpan Lunagariya (e6data computing) created CALCITE-7450:
-------------------------------------------------------------
Summary: Bug in ValuesReduceRule dropping LogicalValues incorrectly
Key: CALCITE-7450
URL: https://issues.apache.org/jira/browse/CALCITE-7450
Project: Calcite
Issue Type: Bug
Components: core
Affects Versions: 1.41.0, 1.42.0
Reporter: Darpan Lunagariya (e6data computing)
When we have *custom functions* defined and use them on LogicalValues, the
ValuesReduceRule will drop the tuples in a wrong way, which it should not do.
The project expression reduction handles it correctly and it specifically
checks that after reduction, did the RexCall reduced into RexLiteral or not, if
not, then we return at that time, but this is not handled in filter expression
reduction.
Below are the relevant snippets from that rule:
*For project:*
{code:java}
if (projectExprs != null) {
++changeCount;
final ImmutableList.Builder<RexLiteral> tupleBuilder =
ImmutableList.builder();
for (; i < fieldsPerRow; ++i) {
final RexNode reducedValue =
reducibleExps.get((row * fieldsPerRow) + i);
if (reducedValue instanceof RexLiteral) {
tupleBuilder.add((RexLiteral) reducedValue);
} else if (RexUtil.isNullLiteral(reducedValue, true)) {
tupleBuilder.add(rexBuilder.makeNullLiteral(reducedValue.getType()));
} else {
return;
}
}
valuesList = tupleBuilder.build();
} else {
valuesList = values.getTuples().get(row);
}
{code}
*For filter:*
{code:java}
if (conditionExpr != null) {
final RexNode reducedValue =
reducibleExps.get((row * fieldsPerRow) + i);
++i;
if (!reducedValue.isAlwaysTrue()) {
++changeCount;
continue;
}
}
{code}
For filter conditions, we just check
{code:java}
!reducedValue.isAlwaysTrue(){code}
which will always be true in case of RexCall and that tuple will be dropped
incorrectly, instead, we should just return from that rule, as done in reducing
the project expression.
Here is one example:
{code:sql}
SELECT * FROM (VALUES (0, 1, 2), (3, 4, 5)) AS t(a, b, c) WHERE
CUSTOM_FUNC(t.a) > 2
{code}
I have just registered CUSTOM_FUNC in operator table, but I did not register
Janino CallImplementor. Possibility is that this function is executed at
runtime and some application just expect calcite to produce the Plan for it.
For this query,
{code:java}
// RelNode tree after conversion to RelNode from SqlNode:
LogicalProject(A=[$0], B=[$1], C=[$2])
LogicalFilter(condition=[>(CUSTOM_FUNC($0), 2)])
LogicalValues(tuples=[[{ 0, 1, 2 }, { 3, 4, 5 }]])
// RelNode tree applying the rule:
LogicalValues(tuples=[[]])
{code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)