use of com.hazelcast.jet.sql.impl.validate.operators.json.HazelcastJsonValueFunction in project hazelcast by hazelcast.
the class HazelcastSqlToRelConverter method convertCall.
/**
* This method overcomes a bug in Apache Calcite that ignores previously resolved return types of the expression
* and instead attempts to infer them again using a different logic. Without this fix, we will get type resolution
* errors after a SQL-to-rel conversion.
* <p>
* The method relies on the fact that all operators use {@link HazelcastReturnTypeInference} as a top-level return type
* inference method.
* <ul>
* <li>When a call node is observed for the first time, get its return type and save it to a thread-local variable
* <li>Then delegate back to original converter code
* <li>When converter attempts to resolve the return type of a call, it will get the previously saved type from
* the thread-local variable
* </ul>
*/
private RexNode convertCall(SqlNode node, Blackboard blackboard) {
// for DEFAULT node, it will fail.
if (node.getKind() == SqlKind.DEFAULT) {
return null;
}
if (((SqlCall) node).getOperator() instanceof HazelcastJsonValueFunction) {
return convertJsonValueCall((SqlCall) node, blackboard);
}
if (callSet.add(node)) {
try {
RelDataType type = validator.getValidatedNodeType(node);
HazelcastReturnTypeInference.push(type);
try {
return blackboard.convertExpression(node);
} catch (RuntimeException e) {
// For some operators Calcite does reflective call to validate the AST
if (e.getCause() instanceof InvocationTargetException && e.getCause().getCause() instanceof QueryException) {
throw (QueryException) e.getCause().getCause();
} else {
throw e;
}
} finally {
HazelcastReturnTypeInference.pop();
}
} finally {
callSet.remove(node);
}
}
return null;
}
Aggregations