fix:修复别名映射和字段增加空格解析错误问题

This commit is contained in:
rulego-team
2025-06-15 21:32:44 +08:00
parent f8b4924d03
commit 368b33ae34
4 changed files with 126 additions and 29 deletions

View File

@ -40,34 +40,67 @@ type ExpressionEvaluator struct {
}
func NewGroupAggregator(groupFields []string, fieldMap map[string]AggregateType, fieldAlias map[string]string) *GroupAggregator {
aggregators := make(map[string]AggregatorFunction)
// 重新组织 fieldMap 和 fieldAlias
// 测试中fieldMap: {"temperature": Sum}, fieldAlias: {"temperature": "temperature_sum"}
// 这意味着:输入字段"temperature"聚合类型Sum输出别名"temperature_sum"
// 处理两种可能的调用模式:
// 1. SQL解析模式fieldMap是输出字段名->聚合类型fieldAlias是输出字段名->输入字段名
// 2. 直接测试模式fieldMap是输入字段名->聚合类型fieldAlias是输入字段名->输出字段名
// 创建的映射:输出字段名 -> 聚合类型
newFieldMap := make(map[string]AggregateType)
// 创建新的别名映射:输出字段名 -> 输入字段名
newFieldAlias := make(map[string]string)
// 创建最终的映射
finalFieldMap := make(map[string]AggregateType)
finalFieldAlias := make(map[string]string)
for inputField, aggType := range fieldMap {
outputField := inputField // 默认输出字段名等于输入字段名
if alias, exists := fieldAlias[inputField]; exists {
outputField = alias // 如果有别名,使用别名作为输出字段名
// 简化的检测逻辑:
// 在直接测试模式中fieldAlias 的值通常包含 "_sum", "_avg" 等后缀
// 在SQL解析模式中fieldAlias 的值是实际的数据字段名(如 "temperature"
isSQLMode := false
if len(fieldAlias) > 0 {
// 检查是否有任何 fieldAlias 的值看起来像 SQL 解析模式(不包含聚合后缀)
for _, aliasValue := range fieldAlias {
// 如果值不包含典型的聚合后缀可能是SQL模式
if !strings.Contains(aliasValue, "_sum") &&
!strings.Contains(aliasValue, "_avg") &&
!strings.Contains(aliasValue, "_min") &&
!strings.Contains(aliasValue, "_max") &&
!strings.Contains(aliasValue, "_count") {
isSQLMode = true
break
}
}
}
newFieldMap[outputField] = aggType
newFieldAlias[outputField] = inputField
aggregators[outputField] = CreateBuiltinAggregator(aggType)
if isSQLMode {
// SQL解析模式fieldMap是输出字段名->聚合类型fieldAlias是输出字段名->输入字段名
finalFieldMap = fieldMap
finalFieldAlias = fieldAlias
} else {
// 直接测试模式fieldMap是输入字段名->聚合类型fieldAlias是输入字段名->输出字段名
for inputField, aggType := range fieldMap {
outputField := inputField // 默认输出字段名等于输入字段名
// fieldAlias提供了输入字段名 -> 输出别名的映射
if alias, exists := fieldAlias[inputField]; exists {
outputField = alias
}
finalFieldMap[outputField] = aggType
finalFieldAlias[outputField] = inputField
}
}
// 创建聚合器
for outputField := range finalFieldMap {
aggregators[outputField] = CreateBuiltinAggregator(finalFieldMap[outputField])
}
return &GroupAggregator{
fieldMap: newFieldMap, // 输出字段名 -> 聚合类型
fieldMap: finalFieldMap, // 输出字段名 -> 聚合类型
groupFields: groupFields,
aggregators: aggregators,
groups: make(map[string]map[string]AggregatorFunction),
fieldAlias: newFieldAlias, // 输出字段名 -> 输入字段名
fieldAlias: finalFieldAlias, // 输出字段名 -> 输入字段名
expressions: make(map[string]*ExpressionEvaluator),
}
}
@ -214,8 +247,8 @@ func (ga *GroupAggregator) Add(data interface{}) error {
// 获取实际的输入字段名
// field现在是输出字段名可能是别名需要找到对应的输入字段名
inputFieldName := field
// 在聚合器内部fieldAlias的映射方向是输出字段名 -> 输入字段名
if mappedField, exists := ga.fieldAlias[field]; exists {
// 如果field是别名获取实际输入字段名
inputFieldName = mappedField
}