1. Flink 中函数的作用
1.1 在 Table API & SQL 中,函数用于表达各种数据转换:字段计算、格式处理、聚合、条件分支、时间处理、解析/序列化等。
1.2 Flink 通过函数体系,把复杂的业务逻辑封装为可复用的"计算单元",并在 SQL 执行时完成函数查找与绑定。
2. 函数的两条分类维度
2.1 维度一:系统(Built-in/System)函数 vs Catalog 函数
2.1.1 系统函数(System Functions)
- 没有命名空间(namespace)
- 在 SQL 中直接用函数名调用:
myfunc(x) - 典型是 Flink 内置函数(或系统提供的持久函数)
2.1.2 Catalog 函数(Catalog Functions)
-
归属于某个 Catalog 与 Database,因此具备命名空间
-
可用多种限定方式引用:
- 全限定:
catalog.db.func(x) - 半限定:
db.func(x) - 或仅函数名:
func(x)(此时走模糊解析)
- 全限定:
2.2 维度二:临时函数 vs 持久函数
2.2.1 临时函数(Temporary Functions)
- 会话级(session scope)
- 生命周期只到会话结束
- 必定由用户创建(比如在 SQL Client/应用会话中注册)
2.2.2 持久函数(Persistent Functions)
- 跨会话存在
- 可能来自系统预置,也可能持久化在 Catalog 中
3. 两条维度组合后的 4 类函数
3.1 Temporary System Functions(临时系统函数)
- 无命名空间
- 会话级可见,优先级通常最高(模糊引用时)
3.2 System Functions(系统函数)
- 无命名空间
- 系统内置/系统提供,跨会话可用
3.3 Temporary Catalog Functions(临时 Catalog 函数)
- 有命名空间(catalog/db 语境)
- 会话级存在
3.4 Catalog Functions(Catalog 持久函数)
- 有命名空间
- 持久化在 Catalog 中,跨会话存在
4. SQL 中引用函数的两种方式
4.1 精确引用(Precise Function Reference)
4.1.1 目的:
- 明确指定要用哪个 Catalog/Database 下的函数,避免歧义
- 支持跨 Catalog、跨 Database 调用
4.1.2 写法示例:
-
全限定:
SELECT mycatalog.mydb.myfunc(x) FROM mytable;
-
半限定:
SELECT mydb.myfunc(x) FROM mytable;
4.1.3 版本说明:
- 精确引用从 Flink 1.10 开始支持
4.1.4 重要限制:
-
系统函数没有 namespace,因此"精确引用"在 Flink 中必然指向:
- 临时 Catalog 函数 或
- Catalog 持久函数
-
换句话说:你不可能用
catalog.db.xxx的方式指向 system function。
4.2 模糊引用(Ambiguous Function Reference)
4.2.1 目的:
- 写起来简洁:只写函数名,让 Flink 按规则自动解析
- 适用于不会发生同名冲突的场景
4.2.2 写法示例:
SELECT myfunc(x) FROM mytable;
5. 同名冲突时:函数解析优先级(Resolution Order)
只有当存在"同名不同类型函数"时,解析顺序才会影响最终调用哪个函数。
如果没有冲突,Flink 直接解析到唯一函数,不会走复杂优先级。
5.1 精确引用的解析顺序
5.1.1 适用范围:
-
因为 system functions 没有 namespace,所以精确引用只会命中:
- 临时 Catalog 函数
- Catalog 持久函数
5.1.2 解析顺序(从高到低):
- Temporary catalog function
- Catalog function
5.2 模糊引用的解析顺序
5.2.1 解析顺序(从高到低):
- Temporary system function
- System function
- Temporary catalog function(当前会话的 current catalog + current database)
- Catalog function(当前会话的 current catalog + current database)
6. 一句话记忆法(很实用)
6.1 模糊引用 :先看"会话里有没有临时的",再看系统内置,最后才看当前 catalog/db 的函数。
6.2 精确引用:只在 catalog 函数里找,先临时 catalog,再持久 catalog。
7. 实战建议:怎么避免踩坑
7.1 生产环境尽量避免与系统函数同名(例如 to_timestamp 这类名字),否则团队协作时很容易"你以为调用的是 A,其实调用的是 B"。
7.2 需要跨 catalog/db 共享逻辑时,优先用 精确引用 (catalog.db.func()),可读性与可控性更强。
7.3 在 SQL Client/Notebook 里做实验时用临时函数没问题,但要记得它们"会话结束就消失",上线前要么固化为 catalog 持久函数,要么写进作业初始化逻辑。