Presto自定义函数@SqlNullable引发问题详解

 更新时间:2022年12月05日 11:39:21   作者:EdurtIO  
这篇文章主要为大家介绍了Presto自定义函数@SqlNullable引发问题详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引发Presto问题

看到标题我们会想到是由于@SqlNullable注解引发的问题,我们先看一段代码,正是这段有意思的代码,让我纠结了2个多小时,引发了Presto的问题。

@Description("user_id")
@ScalarFunction("user_id")
@SqlType(StandardTypes.VARCHAR)
public static Slice userId(@SqlType(StandardTypes.VARCHAR) Slice value) {
    String _value = value.toStringUtf8();
    if (StringUtils.containsWhitespace(_value)) {
        _value = StringUtils.replace(_value, " ", "+");
    } 
    return Slices.utf8Slice(makeErrorMsgBase64(_value));
}

这段代码很简单,就是我们将传递进来的base64的字符串解码成实际的字符串,单单从代码上看是不会有什么问题的。当我们实际运行这个函数的时候问题就出现了,以下是一个使用示例:

select user_id(str) from temp.users limit 100;

看执行的SQL似乎也没有什么异常,但就是这么简简单单的一个函数引发了Presto的问题,那就是java.lang.NullPointerException: undefined错误

错误具体内容

java.lang.NullPointerException: undefined
	at io.prestosql.type.VarcharOperators.equal(VarcharOperators.java:53)
	at io.prestosql.$gen.CursorProcessor_20200927_063218_2398.filter(Unknown Source)
	at io.prestosql.$gen.CursorProcessor_20200927_063218_2398.process(Unknown Source)
	at io.prestosql.operator.ScanFilterAndProjectOperator$RecordCursorToPages.process(ScanFilterAndProjectOperator.java:323)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorUtils.getNextState(WorkProcessorUtils.java:221)
	at io.prestosql.operator.WorkProcessorUtils$YieldingProcess.process(WorkProcessorUtils.java:181)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorUtils.getNextState(WorkProcessorUtils.java:221)
	at io.prestosql.operator.WorkProcessorUtils.lambda$processStateMonitor$2(WorkProcessorUtils.java:200)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorUtils.lambda$flatten$6(WorkProcessorUtils.java:277)
	at io.prestosql.operator.WorkProcessorUtils$3.process(WorkProcessorUtils.java:319)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorUtils$3.process(WorkProcessorUtils.java:306)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorUtils.getNextState(WorkProcessorUtils.java:221)
	at io.prestosql.operator.WorkProcessorUtils.lambda$processStateMonitor$2(WorkProcessorUtils.java:200)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorUtils.getNextState(WorkProcessorUtils.java:221)
	at io.prestosql.operator.WorkProcessorUtils.lambda$finishWhen$3(WorkProcessorUtils.java:215)
	at io.prestosql.operator.WorkProcessorUtils$ProcessWorkProcessor.process(WorkProcessorUtils.java:372)
	at io.prestosql.operator.WorkProcessorSourceOperatorAdapter.getOutput(WorkProcessorSourceOperatorAdapter.java:149)
	at io.prestosql.operator.Driver.processInternal(Driver.java:379)
	at io.prestosql.operator.Driver.lambda$processFor$8(Driver.java:283)
	at io.prestosql.operator.Driver.tryWithLock(Driver.java:675)
	at io.prestosql.operator.Driver.processFor(Driver.java:276)
	at io.prestosql.execution.SqlTaskExecution$DriverSplitRunner.processFor(SqlTaskExecution.java:1076)
	at io.prestosql.execution.executor.PrioritizedSplitRunner.process(PrioritizedSplitRunner.java:shichengoooo@163.com)
	at io.prestosql.execution.executor.TaskExecutor$TaskRunner.run(TaskExecutor.java:484)
	at io.prestosql.$gen.Presto_341____20200925_110330_2.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)

修改UDF源码

通过上面错误我们推算出应该是由于数据导致空指针异常,那么问题出在哪里呢?问题就出在查询str这个字段中,这个字段我们经过实际的查询发现是有''的数据,在做转换的时候出现了空指针问题,于是我们修改UDF的源码为

@Description("user_id")
@ScalarFunction("user_id")
@SqlType(StandardTypes.VARCHAR)
@SqlNullable
public static Slice userId(@SqlNullable @SqlType(StandardTypes.VARCHAR) Slice value) {
    String _value = value.toStringUtf8();
    if (StringUtils.containsWhitespace(_value)) {
        _value = StringUtils.replace(_value, " ", "+");
    } 
    return Slices.utf8Slice(makeErrorMsgBase64(_value));
}

我们在方法和参数上添加了@SqlNullable注解用于标记此函数可以接收空的数据,这似乎看着也没有问题,我们将该函数重新发布,再次执行SQL发现还存在相同的问题,于是又将代码修改为以下内容

@Description("user_id")
@ScalarFunction("user_id")
@SqlType(StandardTypes.VARCHAR)
public static Slice userId(@SqlNullable @SqlType(StandardTypes.VARCHAR) Slice value) {
    String _value = value.toStringUtf8();
    if (StringUtils.containsWhitespace(_value)) {
        _value = StringUtils.replace(_value, " ", "+");
    } 
    return Slices.utf8Slice(makeErrorMsgBase64(_value));
}

删除了方法上的@SqlNullable注解,再次运行发现不会再出现这个错误,但是Presto服务中不断的报出空指针错误,只是不在反馈给查询客户端,原本以为此问题已经解决,然而更有意思的事情发生了,我们使用了343版本测试成功后,线上版本是341,升级线上后发现此问题再次复现,如果再次在方法上加上@SqlNullable注解在341版本上又会修复这个问题,目前已将这个问题反馈给官方,推荐大家使用343版本!

以上就是Presto自定义函数@SqlNullable引发问题详解的详细内容,更多关于Presto自定义函数@SqlNullable的资料请关注脚本之家其它相关文章!

相关文章

  • Java中字符串与byte数组之间的相互转换

    Java中字符串与byte数组之间的相互转换

    Java语言中字符串类型和字节数组类型相互之间的转换经常发生,网上的分析及代码也比较多,这篇文章将主要介绍Java中字符串与byte数组之间的相互转换,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-10-10
  • SpringBoot+MinIO实现文件上传、读取、下载、删除的使用示例

    SpringBoot+MinIO实现文件上传、读取、下载、删除的使用示例

    本文主要介绍了SpringBoot+MinIO实现文件上传、读取、下载、删除的使用示例,详细介绍每个功能实现的步骤和代码示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • Java实现的自定义迭代器功能示例

    Java实现的自定义迭代器功能示例

    这篇文章主要介绍了Java实现的自定义迭代器功能,结合具体实例形式分析了java简单迭代器的实现步骤与相关操作技巧,需要的朋友可以参考下
    2017-04-04
  • java页面中文乱码的解决办法

    java页面中文乱码的解决办法

    做java开发的朋友碰到最多的就是中文乱码这个问题了,下面介绍页面提交时与url中文乱码的一些解决办法
    2013-11-11
  • SpringBoot SSE服务端主动推送事件的实现

    SpringBoot SSE服务端主动推送事件的实现

    本文主要介绍了SpringBoot SSE服务端主动推送事件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 通过dom4j解析xml字符串(示例代码)

    通过dom4j解析xml字符串(示例代码)

    本篇文章主要是对通过dom4j解析xml字符串的示例代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • Feign调用中的两种Header传参方式小结

    Feign调用中的两种Header传参方式小结

    这篇文章主要介绍了Feign调用中的两种Header传参方式小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • 详解阿里云maven镜像库配置(gradle,maven)

    详解阿里云maven镜像库配置(gradle,maven)

    这篇文章主要介绍了详解阿里云maven镜像库配置(gradle,maven),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • java递归处理单位人员组织机构树方式

    java递归处理单位人员组织机构树方式

    这篇文章主要介绍了java递归处理单位人员组织机构树方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Spring Boot 微信小程序接入微信支付功能

    Spring Boot 微信小程序接入微信支付功能

    本文详细介绍了使用SpringBoot框架接入微信支付的全流程,包括导入依赖、配置微信公众号信息、设置配置文件、编写支付相关实体类和API地址常量、实现支付服务以及Controller层的编写,感兴趣的朋友跟随小编一起看看吧
    2024-09-09

最新评论