When we have a dynamic function like
in the query, calcite will skip constant reduction, for example, for query1:
The plan after rule `ReduceExpressionsRule.PROJECT_INSTANCE` is
This is as expect cause there is such code snippet in `ReducibleExprLocator#visitCall`:
But for query2:
we will get a plan with rule `ReduceExpressionsRule.PROJECT_INSTANCE` as:
This is actually wrong cause `current_timestamp` is dynamic and we do not want to compute it again in the outer project.
The reason we did constant reduction is that: for query2, we will get a pulled up predicates with tool function `RexUtil.isConstant`, this function decide if the call is constant by invoking `SqlOperator#isDeterministic` which is default true here. It did not do the `isDynamicFunction()` decision just like `ReducibleExprLocator` and the reduction finally happened which handle by `RexExecutor`.
Personally i think we should keep sync in reduction logic for `inputRef` and `RexCall` and i reuse the `analyzeCall` and apply a patch here.