feat:HAVING子句中支持CASE表达式

This commit is contained in:
rulego-team
2025-06-16 20:25:27 +08:00
parent 1500dc5d23
commit 89d0878913

View File

@ -409,36 +409,70 @@ func (s *Stream) process() {
// 应用 HAVING 过滤条件 // 应用 HAVING 过滤条件
if s.config.Having != "" { if s.config.Having != "" {
// 预处理HAVING条件中的LIKE语法转换为expr-lang可理解的形 // 检查HAVING条件是否包含CASE表达
processedHaving := s.config.Having hasCaseExpression := strings.Contains(strings.ToUpper(s.config.Having), "CASE")
bridge := functions.GetExprBridge()
if bridge.ContainsLikeOperator(s.config.Having) {
if processed, err := bridge.PreprocessLikeExpression(s.config.Having); err == nil {
processedHaving = processed
}
}
// 预处理HAVING条件中的IS NULL语法 var filteredResults []map[string]interface{}
if bridge.ContainsIsNullOperator(processedHaving) {
if processed, err := bridge.PreprocessIsNullExpression(processedHaving); err == nil {
processedHaving = processed
}
}
// 创建 HAVING 条件 if hasCaseExpression {
havingFilter, err := condition.NewExprCondition(processedHaving) // HAVING条件包含CASE表达式使用我们的表达式解析器
if err != nil { expression, err := expr.NewExpression(s.config.Having)
logger.Error("having filter error: %v", err) if err != nil {
} else { logger.Error("having filter error (CASE expression): %v", err)
// 应用 HAVING 过滤 } else {
var filteredResults []map[string]interface{} // 应用 HAVING 过滤使用CASE表达式计算器
for _, result := range finalResults { for _, result := range finalResults {
if havingFilter.Evaluate(result) { // 使用EvaluateWithNull方法以支持NULL值处理
filteredResults = append(filteredResults, result) havingResult, isNull, err := expression.EvaluateWithNull(result)
if err != nil {
logger.Error("having filter evaluation error: %v", err)
continue
}
// 如果结果是NULL则不满足条件SQL标准行为
if isNull {
continue
}
// 对于数值结果大于0视为true满足HAVING条件
if havingResult > 0 {
filteredResults = append(filteredResults, result)
}
}
}
} else {
// HAVING条件不包含CASE表达式使用原有的expr-lang处理
// 预处理HAVING条件中的LIKE语法转换为expr-lang可理解的形式
processedHaving := s.config.Having
bridge := functions.GetExprBridge()
if bridge.ContainsLikeOperator(s.config.Having) {
if processed, err := bridge.PreprocessLikeExpression(s.config.Having); err == nil {
processedHaving = processed
}
}
// 预处理HAVING条件中的IS NULL语法
if bridge.ContainsIsNullOperator(processedHaving) {
if processed, err := bridge.PreprocessIsNullExpression(processedHaving); err == nil {
processedHaving = processed
}
}
// 创建 HAVING 条件
havingFilter, err := condition.NewExprCondition(processedHaving)
if err != nil {
logger.Error("having filter error: %v", err)
} else {
// 应用 HAVING 过滤
for _, result := range finalResults {
if havingFilter.Evaluate(result) {
filteredResults = append(filteredResults, result)
}
} }
} }
finalResults = filteredResults
} }
finalResults = filteredResults
} }
// 应用 LIMIT 限制 // 应用 LIMIT 限制