in core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java [1996:2140]
throw handleUnresolvedFunction(sqlCall, operator,
ImmutableList.of(), null);
}
return sqlCall;
}
}
}
return null;
}
@Override public RelDataType deriveType(
SqlValidatorScope scope,
SqlNode expr) {
requireNonNull(scope, "scope");
requireNonNull(expr, "expr");
// if we already know the type, no need to re-derive
RelDataType type = nodeToTypeMap.get(expr);
if (type != null) {
return type;
}
final SqlValidatorNamespace ns = getNamespace(expr);
if (ns != null) {
return ns.getType();
}
type = deriveTypeImpl(scope, expr);
requireNonNull(type, "SqlValidator.deriveTypeInternal returned null");
setValidatedNodeType(expr, type);
return type;
}
/**
* Derives the type of a node, never null.
*/
RelDataType deriveTypeImpl(
SqlValidatorScope scope,
SqlNode operand) {
DeriveTypeVisitor v = new DeriveTypeVisitor(scope);
final RelDataType type = operand.accept(v);
return requireNonNull(scope.nullifyType(operand, type));
}
@Override public RelDataType deriveConstructorType(
SqlValidatorScope scope,
SqlCall call,
SqlFunction unresolvedConstructor,
@Nullable SqlFunction resolvedConstructor,
List<RelDataType> argTypes) {
SqlIdentifier sqlIdentifier = unresolvedConstructor.getSqlIdentifier();
requireNonNull(sqlIdentifier, "sqlIdentifier");
RelDataType type = catalogReader.getNamedType(sqlIdentifier);
if (type == null) {
// TODO jvs 12-Feb-2005: proper type name formatting
throw newValidationError(sqlIdentifier,
RESOURCE.unknownDatatypeName(sqlIdentifier.toString()));
}
if (resolvedConstructor == null) {
if (call.operandCount() > 0) {
// This is not a default constructor invocation, and
// no user-defined constructor could be found
throw handleUnresolvedFunction(call, unresolvedConstructor, argTypes,
null);
}
} else {
SqlCall testCall =
resolvedConstructor.createCall(
call.getParserPosition(),
call.getOperandList());
RelDataType returnType =
resolvedConstructor.validateOperands(
this,
scope,
testCall);
assert type == returnType;
}
if (config.identifierExpansion()) {
if (resolvedConstructor != null) {
((SqlBasicCall) call).setOperator(resolvedConstructor);
} else {
// fake a fully-qualified call to the default constructor
((SqlBasicCall) call).setOperator(
new SqlFunction(
requireNonNull(type.getSqlIdentifier(), () -> "sqlIdentifier of " + type),
ReturnTypes.explicit(type),
null,
null,
null,
SqlFunctionCategory.USER_DEFINED_CONSTRUCTOR));
}
}
return type;
}
@Override public CalciteException handleUnresolvedFunction(SqlCall call,
SqlOperator unresolvedFunction, List<RelDataType> argTypes,
@Nullable List<String> argNames) {
// For builtins, we can give a better error message
final List<SqlOperator> overloads = new ArrayList<>();
opTab.lookupOperatorOverloads(unresolvedFunction.getNameAsId(), null,
SqlSyntax.FUNCTION, overloads, catalogReader.nameMatcher());
if (overloads.size() == 1) {
SqlFunction fun = (SqlFunction) overloads.get(0);
if ((fun.getSqlIdentifier() == null)
&& (fun.getSyntax() != SqlSyntax.FUNCTION_ID
&& fun.getSyntax() != SqlSyntax.FUNCTION_ID_CONSTANT)) {
final int expectedArgCount =
fun.getOperandCountRange().getMin();
throw newValidationError(call,
RESOURCE.invalidArgCount(call.getOperator().getName(),
expectedArgCount));
}
}
final String signature;
if (unresolvedFunction instanceof SqlFunction) {
final SqlOperandTypeChecker typeChecking =
new AssignableOperandTypeChecker(argTypes, argNames);
signature =
typeChecking.getAllowedSignatures(unresolvedFunction,
unresolvedFunction.getName());
} else {
signature = unresolvedFunction.getName();
}
throw newValidationError(call,
RESOURCE.validatorUnknownFunction(signature));
}
protected void inferUnknownTypes(
RelDataType inferredType,
SqlValidatorScope scope,
SqlNode node) {
requireNonNull(inferredType, "inferredType");
requireNonNull(scope, "scope");
requireNonNull(node, "node");
final SqlValidatorScope newScope = scopes.get(node);
if (newScope != null) {
scope = newScope;
}
boolean isNullLiteral = SqlUtil.isNullLiteral(node, false);
if ((node instanceof SqlDynamicParam) || isNullLiteral) {
if (inferredType.equals(unknownType)) {
if (isNullLiteral) {
if (config.typeCoercionEnabled()) {