private static RelDataType convertToSql(final RelDataTypeFactory typeFactory,
      RelDataType type) {
    if (type instanceof RelRecordType) {
      return typeFactory.createStructType(
          Lists.transform(type.getFieldList(), a0 -> convertToSql(typeFactory, a0.getType())),
          type.getFieldNames());
    }
    if (type instanceof JavaType) {
      SqlTypeName typeName = JavaToSqlTypeConversionRules.instance().lookup(((JavaType) type).getJavaClass());
      // For unknown sql type names, return ANY sql type to make Calcite validation not fail.
      if (typeName == null) {
        typeName = SqlTypeName.ANY;
      }
      return typeFactory.createTypeWithNullability(
          typeFactory.createSqlType(typeName),
          type.isNullable());
    } else {
      return JavaTypeFactoryImpl.toSql(typeFactory, type);
    }
  }
Calcite does validation of projected field types in select statement with the output schema types. If one of the
projected fields is an UDF with return type of {@link Object} or any other java type not defined in
{@link JavaToSqlTypeConversionRules}, using the default {@link JavaTypeFactoryImpl} results in validation failure.
Hence, extending {@link JavaTypeFactoryImpl} to make Calcite validation work with all output types of Samza SQL UDFs.
samza-sql/src/main/java/org/apache/samza/sql/interfaces/SamzaSqlJavaTypeFactoryImpl.java