Java UDF, UDAF, UDTF

数据仓库 PALO

  • 功能发布记录
  • 操作手册1
    • LDAP认证
    • 时区
    • 使用S3-SDK访问对象存储
    • 权限管理
    • 物化视图
    • 变量
    • 资源管理
    • 数据更新与删除
      • 标记删除
      • Sequence-Column
      • 数据更新
      • 数据删除
    • 备份与恢复
      • 备份与恢复
    • 数据导出1
      • SELECT INTO OUTFILE
      • MySQL Dump
      • 数据导出概述
      • Export
    • 数据导出
      • 全量数据导出
      • 导出查询结果集
      • 导出总览
      • 导出数据到外部表
    • 查询加速1
      • 查询缓存
      • 物化视图
        • 同步物化视图
        • 物化视图概览
        • 异步物化视图
          • 异步物化视图常见问题
          • 最佳实践
          • 异步物化视图概述
          • 创建、查询与维护异步物化视图
    • 数据导入
      • JSON格式数据导入说明
      • 导入本地数据
      • 导入BOS中的数据
      • 导入事务和原子性
      • 通过外部表同步数据
      • 使用JDBC同步数据
      • 列的映射、转换与过滤
      • 订阅Kafka日志
      • 严格模式
      • 导入总览
    • 数据更新与删除1
      • 事务
      • 数据更新
        • 主键模型的导入更新
        • 主键模型的 Update 更新
        • 数据更新概述
        • 主键模型的更新并发控制
        • 聚合模型的导入更新
      • 数据删除
        • 删除操作概述
        • Truncate 操作
        • 表原子替换
        • Delete 操作
        • 基于导入的批量删除
        • 临时分区
    • 数据导入1
      • 高并发导入优化(Group Commit)
      • 导入概览
      • 异常数据处理
      • 导入高可用性
      • 导入时实现数据转换
      • 数据源
        • Kafka
        • S3 兼容存储
        • 从其他 TP 系统迁移数据
        • HDFS
        • 从其他 AP 系统迁移数据
        • Flink
        • 本地文件
      • 导入方式
        • Broker Load
        • MySQL Load
        • Insert Into Values
        • Stream Load
        • Insert Into Select
        • Routine Load
      • 文件格式
        • CSV
        • JSON
        • Parquet
        • ORC
      • 复杂数据类型
        • MAP
        • Variant
        • JSON
        • STRUCT
        • Bitmap
        • HLL
        • ARRAY
  • 开发指南
    • 迁移ClickHouse数据
    • Doris集群间数据迁移
    • 数据更新与删除
      • 事务
      • 数据更新
        • 主键模型的导入更新
        • 主键模型的 Update 更新
        • 数据更新概述
        • 主键模型的更新并发控制
        • 聚合模型的导入更新
      • 数据删除
        • 删除操作概述
        • Truncate 操作
        • 表原子替换
        • Delete 操作
        • 基于导入的批量删除
        • 临时分区
    • 查询加速
      • 查询缓存
      • Colocation Join
      • 高并发点查
      • Hint
        • Hint 概述
        • Leading Hint
        • Distribute Hint
      • 物化视图
        • 同步物化视图
        • 物化视图概览
        • 异步物化视图
          • 异步物化视图常见问题
          • 最佳实践
          • 异步物化视图概述
          • 创建、查询与维护异步物化视图
      • 高效去重
        • BITMAP 精准去重
        • HLL 近似去重
      • 优化技术原理
        • TOPN 查询优化
        • 统计信息
        • Pipeline 执行引擎
        • 查询优化器介绍
        • Runtime Filter
      • 查询调优概述
        • 调优概述
        • 诊断工具
        • 分析工具
        • 调优流程
      • 查询优化实践
        • 常见调优参数
        • 计划调优
          • 使用 Hint 控制代价改写
          • 使用异步物化视图透明改写
          • 使用 Leading Hint 控制 Join 顺序
          • 优化表 Schema 设计
          • 使用分区裁剪优化扫表
          • 优化索引设计和使用
          • 使用 Hint 调整 Join Shuffle 方式
          • DML 计划调优
          • 使用 Colocate Group 优化 Join
          • 使用同步物化视图透明改写
          • 使用 SQL Cache 加速查询
        • 执行调优
          • 数据倾斜处理
          • RuntimeFilter 的等待时间调整
          • 并行度调优
    • 数据查询
      • 连接(JOIN)
      • 子查询
      • 复杂类型查询
      • 列转行 (Lateral View)
      • MySQL 兼容性
      • 聚合多维分析
      • 分析函数(窗口函数)
      • 公用表表达式(CTE)
      • 自定义函数
        • 别名函数
        • Java UDF, UDAF, UDTF
    • 数据导出
      • SELECT INTO OUTFILE
      • MySQL Dump
      • 最佳实践
      • 数据导出概述
      • Export
    • 数据导入
      • 高并发导入优化(Group Commit)
      • 异常数据处理
      • 导入高可用性
      • 导入时实现数据转换
      • 导入最佳实践
      • 数据源
        • Kafka
        • Snowflake
        • S3 兼容存储
        • Google Cloud Storage
        • 从其他 TP 系统迁移数据
        • Azure Storage
        • 腾讯云 COS
        • MinIO
        • HDFS
        • 阿里云 OSS
        • 华为云 OBS
        • 从其他 AP 系统迁移数据
        • Flink
        • Redshift
        • Amazon S3
        • 本地文件
        • BigQuery
      • 导入方式
        • Broker Load
        • MySQL Load
        • Insert Into Values
        • Stream Load
        • Insert Into Select
        • Routine Load
      • 文件格式
        • CSV
        • JSON
        • Parquet
        • ORC
      • 复杂数据类型
        • MAP
        • Variant
        • JSON
        • STRUCT
        • Bitmap
        • HLL
        • ARRAY
    • BI工具接入
      • Sugar
      • Navicat
      • Tableau
      • DBeaver
      • 永洪BI
      • FineBI(帆软)
    • 数据库连接
      • 通过 MySQL 协议连接
      • 基于 Arrow Flight SQL 的高速数据传输链路
    • 湖仓一体
      • 分析 S3或HDFS 上的文件
      • 湖仓一体概述
      • SQL 方言兼容
      • 弹性计算节点
      • 云服务认证接入
      • 元数据缓存
      • 外表统计信息
      • 数据缓存
      • 数据库分析
        • MySQL
        • JDBC Catalog
        • Oracle
        • OceanBase
        • SAP HANA
        • 阿里云 MaxCompute
        • ClickHouse
        • PostgreSQL
        • IBM Db2
        • SQL Server
        • Elasticsearch
      • 湖仓一体最佳实践
        • 使用 PALO 和 Paimon
        • 使用 PALO 和 Iceberg
        • 使用 PALO 和 Hudi
        • 使用 PALO 和 LakeSoul
      • 数据湖构建
        • Iceberg
        • Hive
      • 数据湖分析
        • Hudi Catalog
        • 阿里云 DLF
        • Iceberg Catalog
        • Paimon Catalog
        • Hive Catalog
    • 数据表设计
      • 行业混存
      • 数据压缩
      • Schema 变更
      • 数据类型
      • 自增列
      • 概览
      • 数据库建表最佳实践
      • 冷热数据分层
        • SSD 和 HDD 层级存储
        • 远程存储
        • 冷热数据分层概述
      • 表索引
        • 倒排索引
        • 前缀索引与排序键
        • N-Gram 索引
        • BloomFilter 索引
        • 索引概述
      • 数据划分
        • 数据分桶
        • 数据分布概念
        • 动态分区
        • 自动分区
        • 手动分区
        • 常见文档
      • 数据模型
        • 使用注意
        • 模型概述
        • 主键模型
        • 明细模型
        • 聚合模型
  • 版本发布历史
    • 百度数据仓库 Palo 2.0 版本全新发布
  • SQL手册
    • 字面常量
    • 别名
    • SQL-手册
    • 数据类型
    • SQL语句
    • 注释
    • 内置函数
    • 白名单管理
    • SQL操作符
    • 内置函数
      • 聚合函数
      • 位操作函数
      • 字符串函数
      • 条件函数
      • 数学函数
      • JSON解析函数
      • 类型转换函数
      • 格式转换函数
      • 通用函数
      • 时间和日期函数
      • BITMAP函数
      • 窗口函数
      • 哈希函数
      • HLL函数
    • 语法帮助
      • DML
        • INSERT
        • ROUTINE-LOAD
        • RESTORE
        • SELECT-INTO-OUTFILE
        • ALTER-ROUTINE-LOAD
        • BROKER-LOAD
        • BACKUP
        • EXPORT
        • STREAM-LOAD
      • DDL
        • CREATE-FILE
        • DROP-RESOURCE
        • CREATE-RESOURCE
        • CREATE-MATERIALIZED-VIEW
        • DROP-RESROUCE
        • CREATE-TABLE
        • DROP-REPOSITORY
        • CREATE-REPOSITORY
        • CREATE-ODBC-TABLE
      • 信息查看语句
        • SHOW-BACKUP
        • SHOW-ALTER-TABLE-MATERIALIZED-VIEW
        • SHOW-SNAPSHOT
        • SHOW-ROUTINE-LOAD
        • SHOW-CREATE-ROUTINE-LOAD
        • SHOW-ROLES
        • SHOW-GRANTS
        • SHOW-EXPORT
        • SHOW-ROUTINE-LOAD-TASK
        • SHOW-REPOSITORIES
        • SHOW-LOAD
        • SHOW-RESOURCES
        • SHOW-RESTORE
        • SHOW-PROPERTY
        • SHOW-FILE
      • 辅助命令
        • PAUSE-ROUTINE-LOAD
        • STOP-ROUTINE-LOAD
        • ALTER-ROUTINE-LOAD
        • CANCEL-LOAD
        • RESUME-ROUTINE-LOAD
      • 账户管理
        • SET-PROPERTY
        • REVOKE
        • GRANT
        • CREATE-ROLE
        • DROP-ROLE
        • CREATE-USER
        • DROP-USER
        • SET-PASSWORD
  • 快速入门
    • 快速上手
    • 存算分离
    • 存算一体
  • 典型实践
    • 如何开启Debug日志
    • 导入分析
    • 查询分析
  • 操作手册
    • 权限和子用户
    • 存算一体
      • 连接集群
      • 查询分析
      • 监控告警
        • 监控指标
        • 告警配置
      • 备份恢复
        • 通过管理页面备份与恢复
        • 备份与恢复
      • 权限管理
        • 集群权限
        • 控制台权限
      • 集群管理
        • 集群创建
        • 停止与删除
        • 重置管理员密码
        • 集群扩缩容
        • 集群详情
    • 存算分离
      • 连接集群
      • 计算组管理
        • 重启计算组
        • 创建计算组
      • 监控告警
        • 监控指标
        • 告警配置
      • 权限管理
        • 集群权限
        • 控制台权限
      • 集群管理
        • 停止与删除
        • 创建集群
        • 重置管理员密码
        • 集群详情
  • 服务等级协议SLA
    • 服务等级协议(SLA)v1.0
  • 产品概述
    • 系统架构
    • 产品特点
    • 产品介绍
  • 视频专区
    • 操作指南
    • 产品简介
  • 产品定价
    • 预付费
    • 计费说明
    • 后付费
所有文档
menu
没有找到结果,请重新输入

数据仓库 PALO

  • 功能发布记录
  • 操作手册1
    • LDAP认证
    • 时区
    • 使用S3-SDK访问对象存储
    • 权限管理
    • 物化视图
    • 变量
    • 资源管理
    • 数据更新与删除
      • 标记删除
      • Sequence-Column
      • 数据更新
      • 数据删除
    • 备份与恢复
      • 备份与恢复
    • 数据导出1
      • SELECT INTO OUTFILE
      • MySQL Dump
      • 数据导出概述
      • Export
    • 数据导出
      • 全量数据导出
      • 导出查询结果集
      • 导出总览
      • 导出数据到外部表
    • 查询加速1
      • 查询缓存
      • 物化视图
        • 同步物化视图
        • 物化视图概览
        • 异步物化视图
          • 异步物化视图常见问题
          • 最佳实践
          • 异步物化视图概述
          • 创建、查询与维护异步物化视图
    • 数据导入
      • JSON格式数据导入说明
      • 导入本地数据
      • 导入BOS中的数据
      • 导入事务和原子性
      • 通过外部表同步数据
      • 使用JDBC同步数据
      • 列的映射、转换与过滤
      • 订阅Kafka日志
      • 严格模式
      • 导入总览
    • 数据更新与删除1
      • 事务
      • 数据更新
        • 主键模型的导入更新
        • 主键模型的 Update 更新
        • 数据更新概述
        • 主键模型的更新并发控制
        • 聚合模型的导入更新
      • 数据删除
        • 删除操作概述
        • Truncate 操作
        • 表原子替换
        • Delete 操作
        • 基于导入的批量删除
        • 临时分区
    • 数据导入1
      • 高并发导入优化(Group Commit)
      • 导入概览
      • 异常数据处理
      • 导入高可用性
      • 导入时实现数据转换
      • 数据源
        • Kafka
        • S3 兼容存储
        • 从其他 TP 系统迁移数据
        • HDFS
        • 从其他 AP 系统迁移数据
        • Flink
        • 本地文件
      • 导入方式
        • Broker Load
        • MySQL Load
        • Insert Into Values
        • Stream Load
        • Insert Into Select
        • Routine Load
      • 文件格式
        • CSV
        • JSON
        • Parquet
        • ORC
      • 复杂数据类型
        • MAP
        • Variant
        • JSON
        • STRUCT
        • Bitmap
        • HLL
        • ARRAY
  • 开发指南
    • 迁移ClickHouse数据
    • Doris集群间数据迁移
    • 数据更新与删除
      • 事务
      • 数据更新
        • 主键模型的导入更新
        • 主键模型的 Update 更新
        • 数据更新概述
        • 主键模型的更新并发控制
        • 聚合模型的导入更新
      • 数据删除
        • 删除操作概述
        • Truncate 操作
        • 表原子替换
        • Delete 操作
        • 基于导入的批量删除
        • 临时分区
    • 查询加速
      • 查询缓存
      • Colocation Join
      • 高并发点查
      • Hint
        • Hint 概述
        • Leading Hint
        • Distribute Hint
      • 物化视图
        • 同步物化视图
        • 物化视图概览
        • 异步物化视图
          • 异步物化视图常见问题
          • 最佳实践
          • 异步物化视图概述
          • 创建、查询与维护异步物化视图
      • 高效去重
        • BITMAP 精准去重
        • HLL 近似去重
      • 优化技术原理
        • TOPN 查询优化
        • 统计信息
        • Pipeline 执行引擎
        • 查询优化器介绍
        • Runtime Filter
      • 查询调优概述
        • 调优概述
        • 诊断工具
        • 分析工具
        • 调优流程
      • 查询优化实践
        • 常见调优参数
        • 计划调优
          • 使用 Hint 控制代价改写
          • 使用异步物化视图透明改写
          • 使用 Leading Hint 控制 Join 顺序
          • 优化表 Schema 设计
          • 使用分区裁剪优化扫表
          • 优化索引设计和使用
          • 使用 Hint 调整 Join Shuffle 方式
          • DML 计划调优
          • 使用 Colocate Group 优化 Join
          • 使用同步物化视图透明改写
          • 使用 SQL Cache 加速查询
        • 执行调优
          • 数据倾斜处理
          • RuntimeFilter 的等待时间调整
          • 并行度调优
    • 数据查询
      • 连接(JOIN)
      • 子查询
      • 复杂类型查询
      • 列转行 (Lateral View)
      • MySQL 兼容性
      • 聚合多维分析
      • 分析函数(窗口函数)
      • 公用表表达式(CTE)
      • 自定义函数
        • 别名函数
        • Java UDF, UDAF, UDTF
    • 数据导出
      • SELECT INTO OUTFILE
      • MySQL Dump
      • 最佳实践
      • 数据导出概述
      • Export
    • 数据导入
      • 高并发导入优化(Group Commit)
      • 异常数据处理
      • 导入高可用性
      • 导入时实现数据转换
      • 导入最佳实践
      • 数据源
        • Kafka
        • Snowflake
        • S3 兼容存储
        • Google Cloud Storage
        • 从其他 TP 系统迁移数据
        • Azure Storage
        • 腾讯云 COS
        • MinIO
        • HDFS
        • 阿里云 OSS
        • 华为云 OBS
        • 从其他 AP 系统迁移数据
        • Flink
        • Redshift
        • Amazon S3
        • 本地文件
        • BigQuery
      • 导入方式
        • Broker Load
        • MySQL Load
        • Insert Into Values
        • Stream Load
        • Insert Into Select
        • Routine Load
      • 文件格式
        • CSV
        • JSON
        • Parquet
        • ORC
      • 复杂数据类型
        • MAP
        • Variant
        • JSON
        • STRUCT
        • Bitmap
        • HLL
        • ARRAY
    • BI工具接入
      • Sugar
      • Navicat
      • Tableau
      • DBeaver
      • 永洪BI
      • FineBI(帆软)
    • 数据库连接
      • 通过 MySQL 协议连接
      • 基于 Arrow Flight SQL 的高速数据传输链路
    • 湖仓一体
      • 分析 S3或HDFS 上的文件
      • 湖仓一体概述
      • SQL 方言兼容
      • 弹性计算节点
      • 云服务认证接入
      • 元数据缓存
      • 外表统计信息
      • 数据缓存
      • 数据库分析
        • MySQL
        • JDBC Catalog
        • Oracle
        • OceanBase
        • SAP HANA
        • 阿里云 MaxCompute
        • ClickHouse
        • PostgreSQL
        • IBM Db2
        • SQL Server
        • Elasticsearch
      • 湖仓一体最佳实践
        • 使用 PALO 和 Paimon
        • 使用 PALO 和 Iceberg
        • 使用 PALO 和 Hudi
        • 使用 PALO 和 LakeSoul
      • 数据湖构建
        • Iceberg
        • Hive
      • 数据湖分析
        • Hudi Catalog
        • 阿里云 DLF
        • Iceberg Catalog
        • Paimon Catalog
        • Hive Catalog
    • 数据表设计
      • 行业混存
      • 数据压缩
      • Schema 变更
      • 数据类型
      • 自增列
      • 概览
      • 数据库建表最佳实践
      • 冷热数据分层
        • SSD 和 HDD 层级存储
        • 远程存储
        • 冷热数据分层概述
      • 表索引
        • 倒排索引
        • 前缀索引与排序键
        • N-Gram 索引
        • BloomFilter 索引
        • 索引概述
      • 数据划分
        • 数据分桶
        • 数据分布概念
        • 动态分区
        • 自动分区
        • 手动分区
        • 常见文档
      • 数据模型
        • 使用注意
        • 模型概述
        • 主键模型
        • 明细模型
        • 聚合模型
  • 版本发布历史
    • 百度数据仓库 Palo 2.0 版本全新发布
  • SQL手册
    • 字面常量
    • 别名
    • SQL-手册
    • 数据类型
    • SQL语句
    • 注释
    • 内置函数
    • 白名单管理
    • SQL操作符
    • 内置函数
      • 聚合函数
      • 位操作函数
      • 字符串函数
      • 条件函数
      • 数学函数
      • JSON解析函数
      • 类型转换函数
      • 格式转换函数
      • 通用函数
      • 时间和日期函数
      • BITMAP函数
      • 窗口函数
      • 哈希函数
      • HLL函数
    • 语法帮助
      • DML
        • INSERT
        • ROUTINE-LOAD
        • RESTORE
        • SELECT-INTO-OUTFILE
        • ALTER-ROUTINE-LOAD
        • BROKER-LOAD
        • BACKUP
        • EXPORT
        • STREAM-LOAD
      • DDL
        • CREATE-FILE
        • DROP-RESOURCE
        • CREATE-RESOURCE
        • CREATE-MATERIALIZED-VIEW
        • DROP-RESROUCE
        • CREATE-TABLE
        • DROP-REPOSITORY
        • CREATE-REPOSITORY
        • CREATE-ODBC-TABLE
      • 信息查看语句
        • SHOW-BACKUP
        • SHOW-ALTER-TABLE-MATERIALIZED-VIEW
        • SHOW-SNAPSHOT
        • SHOW-ROUTINE-LOAD
        • SHOW-CREATE-ROUTINE-LOAD
        • SHOW-ROLES
        • SHOW-GRANTS
        • SHOW-EXPORT
        • SHOW-ROUTINE-LOAD-TASK
        • SHOW-REPOSITORIES
        • SHOW-LOAD
        • SHOW-RESOURCES
        • SHOW-RESTORE
        • SHOW-PROPERTY
        • SHOW-FILE
      • 辅助命令
        • PAUSE-ROUTINE-LOAD
        • STOP-ROUTINE-LOAD
        • ALTER-ROUTINE-LOAD
        • CANCEL-LOAD
        • RESUME-ROUTINE-LOAD
      • 账户管理
        • SET-PROPERTY
        • REVOKE
        • GRANT
        • CREATE-ROLE
        • DROP-ROLE
        • CREATE-USER
        • DROP-USER
        • SET-PASSWORD
  • 快速入门
    • 快速上手
    • 存算分离
    • 存算一体
  • 典型实践
    • 如何开启Debug日志
    • 导入分析
    • 查询分析
  • 操作手册
    • 权限和子用户
    • 存算一体
      • 连接集群
      • 查询分析
      • 监控告警
        • 监控指标
        • 告警配置
      • 备份恢复
        • 通过管理页面备份与恢复
        • 备份与恢复
      • 权限管理
        • 集群权限
        • 控制台权限
      • 集群管理
        • 集群创建
        • 停止与删除
        • 重置管理员密码
        • 集群扩缩容
        • 集群详情
    • 存算分离
      • 连接集群
      • 计算组管理
        • 重启计算组
        • 创建计算组
      • 监控告警
        • 监控指标
        • 告警配置
      • 权限管理
        • 集群权限
        • 控制台权限
      • 集群管理
        • 停止与删除
        • 创建集群
        • 重置管理员密码
        • 集群详情
  • 服务等级协议SLA
    • 服务等级协议(SLA)v1.0
  • 产品概述
    • 系统架构
    • 产品特点
    • 产品介绍
  • 视频专区
    • 操作指南
    • 产品简介
  • 产品定价
    • 预付费
    • 计费说明
    • 后付费
  • 文档中心
  • arrow
  • 数据仓库PALO
  • arrow
  • 开发指南
  • arrow
  • 数据查询
  • arrow
  • 自定义函数
  • arrow
  • Java UDF, UDAF, UDTF
本页目录
  • 概述
  • 类型对应关系
  • 使用限制
  • 快速上手
  • Java-UDF 实例介绍
  • Java-UDAF 实例介绍
  • Java-UDTF 实例介绍
  • 最佳实践

Java UDF, UDAF, UDTF

更新时间:2025-08-21

概述

Java UDF 为用户提供使用 Java 编写 UDF 的接口,以方便用户使用 Java 语言进行自定义函数的执行。 PALO 支持使用 JAVA 编写 UDF、UDAF 和 UDTF。下文如无特殊说明,使用 UDF 统称所有用户自定义函数。

  1. Java UDF 是较为常见的自定义标量函数 (Scalar Function),即每输入一行数据,就会有一行对应的结果输出,较为常见的有 ABS,LENGTH 等。值得一提的是对于用户来讲,Hive UDF 是可以直接迁移至 PALO 的。
  2. Java UDAF 即为自定义的聚合函数 (Aggregate Function),即在输入多行数据进行聚合后,仅输出一行对应的结果,较为常见的有 MIN,MAX,COUNT 等。
  3. JAVA UDTF 即为自定义的表函数 (Table Function),即每输一行数据,可以产生一行或多行的结果,在 PALO 中需要结合 Lateral View 使用可以达到行转列的效果,较为常见的有 EXPLODE,EXPLODE_SPLIT 等。该功能自 PALO 3.0 版本起开始支持。

类型对应关系

PALO 数据类型 Java UDF 参数类型
Bool Boolean
TinyInt Byte
SmallInt Short
Int Integer
BigInt Long
LargeInt BigInteger
Float Float
Double Double
Date LocalDate
Datetime LocalDateTime
IPV4/IPV6 InetAddress
String String
Decimal BigDecimal
array<Type> ArrayList<Type>(支持嵌套)
map<Type1,Type2> HashMap<Type1,Type2>(支持嵌套)
struct<Type...> ArrayList<Object>(从 3.0.0 版本开始支持)

提示: array、map、struct 类型可以嵌套其它类型。例如,PALO 中的 array<array<int>> 对应 Java UDF 参数类型为 ArrayList<ArrayList<Integer>>,其他类型依此类推。

注意: 在创建函数时,请务必使用 string 类型而不是 varchar,否则可能会导致函数执行失败。

使用限制

  1. 不支持复杂数据类型(HLL,Bitmap)。
  2. 当前允许用户自己指定 JVM 最大堆大小,配置项是 be.conf 中的 JAVA_OPTS 的 -Xmx 部分。默认 1024m,如果需要聚合数据,建议调大一些,增加性能,减少内存溢出风险。
  3. 由于 jvm 加载同名类的问题,不要同时使用多个同名类作为 udf 实现,如果想更新某个同名类的 udf,需要重启 be 重新加载 classpath。

快速上手

本节主要介绍如何开发 Java UDF。在 samples/doris-demo/java-udf-demo/ 目录下提供了示例代码,供您参考。

UDF 的使用与普通的函数方式一致,唯一的区别在于,内置函数的作用域是全局的,而 UDF 的作用域是 DB 内部。 所以如果当前链接 session 位于数据库 DB 内部时,直接使用 UDF 名字会在当前 DB 内部查找对应的 UDF。否则用户需要显示的指定 UDF 的数据库名字,例如 dbName.funcName。

接下来的章节介绍实例,均会在test_table 上做测试,对应建表如下:

SQL
1CREATE TABLE `test_table` (
2    id int NULL,
3    d1 double NULL,
4    str string NULL
5) ENGINE=OLAP
6DUPLICATE KEY(`id`)
7DISTRIBUTED BY HASH(`id`) BUCKETS 1
8PROPERTIES (
9"replication_num" = "1");
10
11insert into test_table values (1, 111.11, "a,b,c");
12insert into test_table values (6, 666.66, "d,e");

Java-UDF 实例介绍

使用 Java 代码编写 UDF,UDF 的主入口必须为 evaluate 函数。这一点与 Hive 等其他引擎保持一致。在本示例中,我们编写了 AddOne UDF 来完成对整型输入进行加一的操作。

  1. 首先编写对应的 Java 代码,打包生成 JAR 包。

    Java
    1public class AddOne extends UDF {
    2    public Integer evaluate(Integer value) {
    3        return value == null ? null : value + 1;
    4    }
    5}
  2. 在 PALO 中注册创建 Java-UDF 函数。

    SQL
    1CREATE FUNCTION java_udf_add_one(int) RETURNS int PROPERTIES (
    2    "file"="file:///path/to/java-udf-demo-jar-with-dependencies.jar",
    3    "symbol"="org.apache.doris.udf.AddOne",
    4    "always_nullable"="true",
    5    "type"="JAVA_UDF"
    6);
  3. 用户使用 UDF 必须拥有对应数据库的 SELECT 权限。 如果想查看注册成功的对应 UDF 函数,可以使用SHOW FUNCTIONS 命令。

    SQL
    1select id,java_udf_add_one(id) from test_table;
    2+------+----------------------+
    3| id   | java_udf_add_one(id) |
    4+------+----------------------+
    5|    1 |                    2 |
    6|    6 |                    7 |
    7+------+----------------------+
  4. 当不再需要 UDF 函数时,可以通过下述命令来删除一个 UDF 函数。

另外,如果定义的 UDF 中需要加载很大的资源文件,或者希望可以定义全局的 static 变量,可以参照文档下方的 static 变量加载方式。

Java-UDAF 实例介绍

在使用 Java 代码编写 UDAF 时,有一些必须实现的函数 (标记 required) 和一个内部类 State,下面将以具体的实例来说明。

  1. 首先编写对应的 Java UDAF 代码,打包生成 JAR 包。
示例 1: SimpleDemo 将实现一个类似的 sum 的简单函数,输入参数 INT,输出参数是 INT
Java
1package org.apache.doris.udf;
2
3import java.io.DataInputStream;
4import java.io.DataOutputStream;
5import java.io.IOException;
6import java.util.logging.Logger;
7
8public class SimpleDemo  {
9
10Logger log = Logger.getLogger("SimpleDemo");
11
12//Need an inner class to store data
13/*required*/
14public static class State {
15    /*some variables if you need */
16    public int sum = 0;
17}
18
19/*required*/
20public State create() {
21    /* here could do some init work if needed */
22    return new State();
23}
24
25/*required*/
26public void destroy(State state) {
27    /* here could do some destroy work if needed */
28}
29
30/*Not Required*/
31public void reset(State state) {
32    /*if you want this udaf function can work with window function.*/
33    /*Must impl this, it will be reset to init state after calculate every window frame*/
34    state.sum = 0;
35}
36
37/*required*/
38//first argument is State, then other types your input
39public void add(State state, Integer val) throws Exception {
40    /* here doing update work when input data*/
41    if (val != null) {
42        state.sum += val;
43    }
44}
45
46/*required*/
47public void serialize(State state, DataOutputStream out) throws IOException {
48    /* serialize some data into buffer */
49    out.writeInt(state.sum);
50}
51
52/*required*/
53public void deserialize(State state, DataInputStream in) throws IOException {
54    /* deserialize get data from buffer before you put */
55    int val = in.readInt();
56    state.sum = val;
57}
58
59/*required*/
60public void merge(State state, State rhs) throws Exception {
61    /* merge data from state */
62    state.sum += rhs.sum;
63}
64
65/*required*/
66//return Type you defined
67public Integer getValue(State state) throws Exception {
68    /* return finally result */
69    return state.sum;
70}
71}
示例 2: MedianUDAF 是一个计算中位数的功能,输入类型为 (DOUBLE, INT), 输出为 DOUBLE
Java
1package org.apache.doris.udf.demo;
2
3import java.io.DataInputStream;
4import java.io.DataOutputStream;
5import java.math.BigDecimal;
6import java.util.Arrays;
7import java.util.logging.Logger;
8
9/*UDAF 计算中位数*/
10public class MedianUDAF {
11Logger log = Logger.getLogger("MedianUDAF");
12
13//状态存储
14public static class State {
15    //返回结果的精度
16    int scale = 0;
17    //是否是某一个 tablet 下的某个聚合条件下的数据第一次执行 add 方法
18    boolean isFirst = true;
19    //数据存储
20    public StringBuilder stringBuilder;
21}
22
23//状态初始化
24public State create() {
25    State state = new State();
26    //根据每个 tablet 下的聚合条件需要聚合的数据量大小,预先初始化,增加性能
27    state.stringBuilder = new StringBuilder(1000);
28    return state;
29}
30
31
32//处理执行单位处理各自 tablet 下的各自聚合条件下的每个数据
33public void add(State state, Double val, int scale) throws IOException {
34    if (val != null && state.isFirst) {
35        state.stringBuilder.append(scale).append(",").append(val).append(",");
36        state.isFirst = false;
37    } else if (val != null) {
38        state.stringBuilder.append(val).append(",");
39    }
40}
41
42//处理数据完需要输出等待聚合
43public void serialize(State state, DataOutputStream out) throws IOException {
44    //目前暂时只提供 DataOutputStream,如果需要序列化对象可以考虑拼接字符串,转换 json,序列化成字节数组等方式
45    //如果要序列化 State 对象,可能需要自己将 State 内部类实现序列化接口
46    //最终都是要通过 DataOutputStream 传输
47    out.writeUTF(state.stringBuilder.toString());
48}
49
50//获取处理数据执行单位输出的数据
51public void deserialize(State state, DataInputStream in) throws IOException {
52    String string = in.readUTF();
53    state.scale = Integer.parseInt(String.valueOf(string.charAt(0)));
54    StringBuilder stringBuilder = new StringBuilder(string.substring(2));
55    state.stringBuilder = stringBuilder;
56}
57
58//聚合执行单位按照聚合条件合并某一个键下数据的处理结果 ,每个键第一次合并时,state1 参数是初始化的实例
59public void merge(State state1, State state2) throws IOException {
60    state1.scale = state2.scale;
61    state1.stringBuilder.append(state2.stringBuilder.toString());
62}
63
64//对每个键合并后的数据进行并输出最终结果
65public Double getValue(State state) throws IOException {
66    String[] strings = state.stringBuilder.toString().split(",");
67    double[] doubles = new double[strings.length + 1];
68    doubles = Arrays.stream(strings).mapToDouble(Double::parseDouble).toArray();
69
70    Arrays.sort(doubles);
71    double n = doubles.length - 1;
72    double index = n * 0.5;
73
74    int low = (int) Math.floor(index);
75    int high = (int) Math.ceil(index);
76
77    double value = low == high ? (doubles[low] + doubles[high]) * 0.5 : doubles[high];
78
79    BigDecimal decimal = new BigDecimal(value);
80    return decimal.setScale(state.scale, BigDecimal.ROUND_HALF_UP).doubleValue();
81}
82
83//每个执行单位执行完都会执行
84public void destroy(State state) {
85}
86
87}
  1. 在 PALO 中注册创建 Java-UADF 函数。

    SQL
    1CREATE AGGREGATE FUNCTION simple_demo(INT) RETURNS INT PROPERTIES (
    2    "file"="file:///pathTo/java-udaf.jar",
    3    "symbol"="org.apache.doris.udf.SimpleDemo",
    4    "always_nullable"="true",
    5    "type"="JAVA_UDF"
    6);
  2. 使用 Java-UDAF, 可以分组聚合或者聚合全部结果:

    SQL
    1select simple_demo(id) from test_table group by id;
    2+-----------------+
    3| simple_demo(id) |
    4+-----------------+
    5|               1 |
    6|               6 |
    7+-----------------+
    SQL
    1select simple_demo(id) from test_table;
    2+-----------------+
    3| simple_demo(id) |
    4+-----------------+
    5|               7 |
    6+-----------------+

Java-UDTF 实例介绍

注意: UDTF 自 PALO 3.0 版本开始支持

最佳实践

Static 变量加载

当前在 PALO 中,执行一个 UDF 函数,例如 select udf(col) from table, 每一个并发 Instance 会加载一次 udf.jar 包,在该 Instance 结束时卸载掉 udf.jar 包。

所以当 udf.jar 文件中需要加载一个几百 MB 的文件时,会因为并发的原因,使得占据的内存急剧增大,容易 OOM。 或者想使用一个连接池时,这样无法做到仅在 static 区域初始化一次。

这里提供两个解决方案,其中方案二需要 PALO 版本在 branch-3.0 以上才行。

解决方案 1:

可以将资源加载代码拆分开,单独生成一个 JAR 包文件,然后其他包直接引用该资源 JAR 包。

假设已经将代码拆分为了 DictLibrary 和 FunctionUdf 两个文件。

Java
1public class DictLibrary {
2    private static HashMap<String, String> res = new HashMap<>();
3
4    static {
5        // suppose we built this dictionary from a certain local file.
6        res.put("key1", "value1");
7        res.put("key2", "value2");
8        res.put("key3", "value3");
9        res.put("0", "value4");
10        res.put("1", "value5");
11        res.put("2", "value6");
12    }
13
14    public static String evaluate(String key) {
15        if (key == null) {
16            return null;
17        }
18        return res.get(key);
19    }
20}
Java
1public class FunctionUdf {
2    public String evaluate(String key) {
3        String value = DictLibrary.evaluate(key);
4        return value;
5    }
6}
  1. 单独编译 DictLibrary 文件,使其生成一个独立的 JAR 包,这样可以得到一个资源文件包 DictLibrary.jar:

    Shell
    1javac   ./DictLibrary.java
    2jar -cf ./DictLibrary.jar ./DictLibrary.class
  2. 编译 FunctionUdf 文件,需要引用上一步得到的资源包作为库使用,这样打包后可以得到 UDF 的 FunctionUdf.jar 包。

    Shell
    1javac -cp ./DictLibrary.jar  ./FunctionUdf.java
    2jar  -cvf ./FunctionUdf.jar  ./FunctionUdf.class
  3. 由于想让资源 JAR 包被所有的并发引用,所以想让它被 JVM 直接加载,可以将它放到指定路径 be/custom_lib 下面,BE 服务重启之后就可以随着 JVM 的启动加载进来,因此都会随着服务启动而加载,停止而释放。
  4. 最后利用 CREATE FUNCTION 语句创建一个 UDF 函数,这样每次卸载仅是 FunctionUdf.jar。

    SQL
    1CREATE FUNCTION java_udf_dict(string) RETURNS string PROPERTIES (
    2 "file"="file:///pathTo/FunctionUdf.jar",
    3 "symbol"="org.apache.doris.udf.FunctionUdf",
    4 "always_nullable"="true",
    5 "type"="JAVA_UDF"
    6);

解决方案 2:

BE 全局缓存 JAR 包,自定义过期淘汰时间,在 create function 时增加两个属性字段,其中 static_load: 用于定义是否使用静态 cache 加载的方式。

expiration_time: 用于定义 JAR 包的过期时间,单位为分钟。

若使用静态 cache 加载方式,则在第一次调用该 UDF 函数时,在初始化之后会将该 UDF 的实例缓存起来,在下次调用该 UDF 时,首先会在 cache 中进行查找,如果没有找到,则会进行相关初始化操作。

并且后台有线程定期检查,如果在配置的过期淘汰时间内,一直没有被调用过,则会从缓存 cache 中清理掉。如果被调用时,则会自动更新缓存时间点。

SQL
1public class Print extends UDF {
2    static Integer val = 0;
3    public Integer evaluate() {
4        val = val + 1;
5        return val;
6    }
7}
SQL
1CREATE FUNCTION print_12() RETURNS int 
2PROPERTIES (
3    "file" = "file:///path/to/java-udf-demo-jar-with-dependencies.jar",
4    "symbol" = "org.apache.doris.udf.Print", 
5    "always_nullable"="true",
6    "type" = "JAVA_UDF",
7    "static_load" = "true", // default value is false
8    "expiration_time" = "60" // default value is 360 minutes
9);

可以看到结果是一直在递增的,证明加载的 JAR 包没有被卸载后又加载,导致重新初始化变量为 0.

SQL
1mysql [test_query_qa]>select print_12();
2+------------+
3| print_12() |
4+------------+
5|          1 |
6+------------+
71 row in set (0.40 sec)
8
9mysql [test_query_qa]>select print_12();
10+------------+
11| print_12() |
12+------------+
13|          2 |
14+------------+
151 row in set (0.03 sec)
16
17mysql [test_query_qa]>select print_12();
18+------------+
19| print_12() |
20+------------+
21|          3 |
22+------------+
231 row in set (0.04 sec)

上一篇
别名函数
下一篇
数据导出