当前位置: 首页 > news >正文

Apache Calcite - 自定义标量函数

前言

上一篇文章中我们介绍了calcite中内置函数的使用。实际需求中会遇到一些场景标准内置函数无法满足需求,这时候就需要用到自定义函数。在 Apache Calcite 中添加自定义函数,以便在 SQL 查询中使用自定义的逻辑。这对于执行特定的数据处理或分析任务非常有用。

相关依赖

通过前面的学习,我们知道表、函数等信息维护在schema中,因此我们要做的事情就是在schema中新增自定义的函数。

以下演示基于1.36版包实现。

    <dependency><groupId>org.apache.calcite</groupId><artifactId>calcite-core</artifactId><version>1.36.0</version></dependency>

为了新增函数我们需要重写AbstractSchema中的 getFunctionMultimap方法,方法定义如下:

  protected Multimap<String, Function> getFunctionMultimap() {return ImmutableMultimap.of();}

Function有多种实现,由于我们要扩展的是标量函数,所以关注ScalarFunction即可。
在这里插入图片描述
这里我们用到ScalarFunctionImpl.create方法来创建标量函数,方法中的参数1是所建函数所在的类,第二个是对应的方法名。

  /*** Creates {@link org.apache.calcite.schema.ScalarFunction} from given class.** <p>If a method of the given name is not found, or it does not suit,* returns {@code null}.** @param clazz class that is used to implement the function* @param methodName Method name (typically "eval")* @return created {@link ScalarFunction} or null*/public static @Nullable ScalarFunction create(Class<?> clazz, String methodName) {final Method method = findMethod(clazz, methodName);if (method == null) {return null;}return create(method);}

实现自定义标量函数

为了方便演示,我们实现一个无用的简单方法,对整数减1

public class CustomFunctions {public static Integer minus1(int num1) {return num1 - 1;}
}

接着扩展前文中用到的schema,实现getFunctionMultimap方法,并增加添加函数的方法

public class ListSchema extends AbstractSchema {Map<String, Table> tableMap = new HashMap<>();Multimap<String, Function> functionMap = LinkedListMultimap.create();public void addTable(String name, Table table) {tableMap.put(name, table);}public void addFunction(String name,Function function) { functionMap.put(name, function);}public ListSchema() {}@Overrideprotected Map<String, Table> getTableMap() {return tableMap;}@Overrideprotected Multimap<String, Function> getFunctionMultimap() {return functionMap;}
}

最后我们在schema中注册函数

ListSchema listSchema = new ListSchema();
listSchema.addFunction("minus1", ScalarFunctionImpl.create(CustomFunctions.class,"minus1"));

完成上述工作后,在sql中使用自定义的函数

ResultSet countResult = statement.executeQuery("select age,listSchema.minus1(age) from listSchema.MyTable");

打印结果,可以看到自定义方法的计算结果

95 94 
21 20 
47 46 

异常处理

在完成上述工作时也遇到了几个异常,分别如下:

No match found for function signature minus1(< NUMERIC>)

  • 详细的异常提示为:java.sql.SQLException: Error while executing SQL “select age,minus1(age) from listSchema.MyTable”: From line 1, column 12 to line 1, column 22: No match found for function signature minus1()
  • 异常原因
    1.注册的方法名与使用方法名不一致。最开始注册时,将方法名首字母写成了大写。但实际使用时却使用的小写名 Minus1 - > minus1 listSchema.addFunction(“Minus1”, ScalarFunctionImpl.create(CustomFunctions.class,“minus1”));
    2.另外使用方法名时没指定schema名,导致了错误
    上述两个问题修改完毕程序正常运行

总结

实现自定义标量函数,注册到schema最后使用,schema是核心,维护了各类元信息,并提供了扩展接口来实现自定义的能力

相关文章:

  • Anaconda创建python环境默认C盘,如何修改路径
  • C语言PTA练习题(期末考试成绩排名,新生舞会,约瑟夫游戏(序号+姓名+密码),排队点名)
  • 【学习Day4】计算机基础
  • 网安速成之选择题(详细解析版)
  • Kmeans聚类模型
  • Polar Web【简单】login
  • 【vue实战项目】通用管理系统:作业列表
  • 【免费Web系列】JavaWeb实战项目案例六
  • 队列——一种操作受限的线性表
  • 【python学习】Anaconda的介绍、下载及conda和pip换源方式(切换到国内镜像源)
  • docker使用docker logs命令查看容器日志的几种方式
  • 出现 Transaction rolled back because it has been marked as rollback-only 解决方法
  • 联邦学习【01】杨强第三章横向联邦学习复现
  • Lombok一文通
  • 杂牌记录仪TS视频流恢复方法
  • 【个人向】《HTTP图解》阅后小结
  • docker-consul
  • iOS | NSProxy
  • JAVA_NIO系列——Channel和Buffer详解
  • spring学习第二天
  • 从重复到重用
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 普通函数和构造函数的区别
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 使用common-codec进行md5加密
  • 数据科学 第 3 章 11 字符串处理
  • 微信小程序开发问题汇总
  • 项目实战-Api的解决方案
  •  一套莫尔斯电报听写、翻译系统
  • 因为阿里,他们成了“杭漂”
  • 说说我为什么看好Spring Cloud Alibaba
  • ​flutter 代码混淆
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #162 (Div. 2)
  • (13)Hive调优——动态分区导致的小文件问题
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (Python) SOAP Web Service (HTTP POST)
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (多级缓存)缓存同步
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)计算机毕业设计ssm电影分享网站
  • (附源码)计算机毕业设计大学生兼职系统
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (理论篇)httpmoudle和httphandler一览
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (转)详解PHP处理密码的几种方式
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • @Autowired标签与 @Resource标签 的区别
  • @RequestParam,@RequestBody和@PathVariable 区别
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [22]. 括号生成
  • [5] CUDA线程调用与存储器架构