mirror of
https://gitee.com/rulego/streamsql.git
synced 2026-03-22 10:05:20 +00:00
221 lines
5.4 KiB
Markdown
221 lines
5.4 KiB
Markdown
# StreamSQL 函数系统
|
||
|
||
StreamSQL 现已支持强大的函数系统,允许在 SQL 查询中使用各种内置函数和自定义函数。
|
||
|
||
## 🚀 主要特性
|
||
|
||
### 1. 模块化函数架构
|
||
- **函数注册器**:统一的函数注册和管理系统
|
||
- **类型安全**:强类型参数验证和转换
|
||
- **可扩展性**:支持运行时注册自定义函数
|
||
- **分类管理**:按功能类型组织函数
|
||
|
||
### 2. 内置函数类别
|
||
|
||
#### 数学函数 (TypeMath)
|
||
- `ABS(x)` - 绝对值
|
||
- `SQRT(x)` - 平方根
|
||
|
||
#### 字符串函数 (TypeString)
|
||
- `CONCAT(str1, str2, ...)` - 字符串连接
|
||
- `LENGTH(str)` - 字符串长度
|
||
- `UPPER(str)` - 转大写
|
||
- `LOWER(str)` - 转小写
|
||
|
||
#### 转换函数 (TypeConversion)
|
||
- `CAST(value, type)` - 类型转换
|
||
- `HEX2DEC(hexStr)` - 十六进制转十进制
|
||
- `DEC2HEX(number)` - 十进制转十六进制
|
||
|
||
#### 时间日期函数 (TypeDateTime)
|
||
- `NOW()` - 当前时间戳
|
||
|
||
### 3. 表达式引擎增强
|
||
- 支持函数调用的复杂表达式
|
||
- 运算符优先级处理
|
||
- 括号分组支持
|
||
- 自动类型转换
|
||
|
||
## 📝 使用示例
|
||
|
||
### 基本函数使用
|
||
|
||
```sql
|
||
-- 数学函数
|
||
SELECT device, ABS(temperature - 20) as deviation
|
||
FROM stream;
|
||
|
||
-- 字符串函数
|
||
SELECT CONCAT(device, '_processed') as processed_name
|
||
FROM stream;
|
||
|
||
-- 表达式中的函数
|
||
SELECT device, AVG(ABS(temperature - 20)) as avg_deviation
|
||
FROM stream
|
||
GROUP BY device, TumblingWindow('1s');
|
||
```
|
||
|
||
### 自定义函数注册
|
||
|
||
```go
|
||
import "github.com/rulego/streamsql/functions"
|
||
|
||
// 注册华氏度转摄氏度函数
|
||
err := functions.RegisterCustomFunction(
|
||
"fahrenheit_to_celsius",
|
||
functions.TypeCustom,
|
||
"温度转换",
|
||
"华氏度转摄氏度",
|
||
1, 1,
|
||
func(ctx *functions.FunctionContext, args []interface{}) (interface{}, error) {
|
||
fahrenheit, err := functions.ConvertToFloat64(args[0])
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
celsius := (fahrenheit - 32) * 5 / 9
|
||
return celsius, nil
|
||
})
|
||
|
||
// 在 SQL 中使用
|
||
sql := `
|
||
SELECT device, AVG(fahrenheit_to_celsius(temperature)) as avg_celsius
|
||
FROM stream
|
||
GROUP BY device, TumblingWindow('2s')
|
||
`
|
||
```
|
||
|
||
### 复合表达式
|
||
|
||
```sql
|
||
-- 复杂的数学表达式
|
||
SELECT
|
||
device,
|
||
AVG(ABS(temperature - 20) * 1.8 + 32) as complex_calc
|
||
FROM stream
|
||
GROUP BY device, TumblingWindow('1s');
|
||
```
|
||
|
||
## 🛠️ 函数开发
|
||
|
||
### 实现自定义函数
|
||
|
||
```go
|
||
// 1. 定义函数结构
|
||
type MyCustomFunction struct {
|
||
*functions.BaseFunction
|
||
}
|
||
|
||
// 2. 实现构造函数
|
||
func NewMyCustomFunction() *MyCustomFunction {
|
||
return &MyCustomFunction{
|
||
BaseFunction: functions.NewBaseFunction(
|
||
"my_func",
|
||
functions.TypeCustom,
|
||
"自定义分类",
|
||
"函数描述",
|
||
1, 3, // 最少1个参数,最多3个参数
|
||
),
|
||
}
|
||
}
|
||
|
||
// 3. 实现验证方法
|
||
func (f *MyCustomFunction) Validate(args []interface{}) error {
|
||
return f.ValidateArgCount(args)
|
||
}
|
||
|
||
// 4. 实现执行方法
|
||
func (f *MyCustomFunction) Execute(ctx *functions.FunctionContext, args []interface{}) (interface{}, error) {
|
||
// 实现具体逻辑
|
||
return result, nil
|
||
}
|
||
|
||
// 5. 注册函数
|
||
functions.Register(NewMyCustomFunction())
|
||
```
|
||
|
||
### 便捷注册方式
|
||
|
||
```go
|
||
// 使用便捷方法注册函数
|
||
err := functions.RegisterCustomFunction(
|
||
"double",
|
||
functions.TypeCustom,
|
||
"数学运算",
|
||
"将数值乘以2",
|
||
1, 1,
|
||
func(ctx *functions.FunctionContext, args []interface{}) (interface{}, error) {
|
||
val, err := functions.ConvertToFloat64(args[0])
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return val * 2, nil
|
||
})
|
||
```
|
||
|
||
## 🧪 测试
|
||
|
||
### 运行函数系统测试
|
||
```bash
|
||
go test ./functions -v
|
||
```
|
||
|
||
### 运行集成测试
|
||
```bash
|
||
go test -v -run TestExpressionInAggregation
|
||
```
|
||
|
||
## 📋 支持的数据类型
|
||
|
||
函数系统支持以下数据类型的自动转换:
|
||
|
||
- **数值类型**: `int`, `int32`, `int64`, `uint`, `uint32`, `uint64`, `float32`, `float64`
|
||
- **字符串类型**: `string`
|
||
- **布尔类型**: `bool`
|
||
- **自动转换**: 字符串数值自动转换为相应的数值类型
|
||
|
||
## 🔧 类型转换工具
|
||
|
||
```go
|
||
// 使用内置转换函数
|
||
val, err := functions.ConvertToFloat64(someValue)
|
||
str, err := functions.ConvertToString(someValue)
|
||
num, err := functions.ConvertToInt64(someValue)
|
||
flag, err := functions.ConvertToBool(someValue)
|
||
```
|
||
|
||
## 📈 性能考虑
|
||
|
||
- **函数注册**: 一次性注册,运行时无开销
|
||
- **类型转换**: 高效的类型检查和转换
|
||
- **表达式缓存**: 表达式解析结果可复用
|
||
- **并发安全**: 函数注册器支持并发访问
|
||
|
||
## 🌟 路线图
|
||
|
||
已实现的功能:
|
||
- ✅ SELECT DISTINCT
|
||
- ✅ LIMIT 子句
|
||
- ✅ HAVING 子句
|
||
- ✅ SESSION 窗口
|
||
- ✅ 函数参数支持表达式运算
|
||
- ✅ 统一函数注册系统
|
||
|
||
待实现的功能:
|
||
- 🔄 更多聚合函数(MEDIAN、STDDEV 等)
|
||
- 🔄 窗口函数(ROW_NUMBER、RANK 等)
|
||
- 🔄 更多时间日期函数
|
||
- 🔄 正则表达式函数
|
||
- 🔄 JSON 处理函数
|
||
|
||
## 🤝 贡献
|
||
|
||
欢迎提交新的函数实现!请遵循以下步骤:
|
||
|
||
1. 在 `functions/` 目录中实现函数
|
||
2. 添加相应的测试用例
|
||
3. 更新文档
|
||
4. 提交 Pull Request
|
||
|
||
---
|
||
|
||
*StreamSQL 函数系统让流处理更加强大和灵活!* 🚀 |