From 89d0878913a1f752cbeb0e16ccc46b9d0694d476 Mon Sep 17 00:00:00 2001 From: rulego-team Date: Mon, 16 Jun 2025 20:25:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:HAVING=E5=AD=90=E5=8F=A5=E4=B8=AD=E6=94=AF?= =?UTF-8?q?=E6=8C=81CASE=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stream/stream.go | 84 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/stream/stream.go b/stream/stream.go index 72b6de3..0da0259 100644 --- a/stream/stream.go +++ b/stream/stream.go @@ -409,36 +409,70 @@ func (s *Stream) process() { // 应用 HAVING 过滤条件 if s.config.Having != "" { - // 预处理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条件是否包含CASE表达式 + hasCaseExpression := strings.Contains(strings.ToUpper(s.config.Having), "CASE") - // 预处理HAVING条件中的IS NULL语法 - if bridge.ContainsIsNullOperator(processedHaving) { - if processed, err := bridge.PreprocessIsNullExpression(processedHaving); err == nil { - processedHaving = processed - } - } + var filteredResults []map[string]interface{} - // 创建 HAVING 条件 - havingFilter, err := condition.NewExprCondition(processedHaving) - if err != nil { - logger.Error("having filter error: %v", err) - } else { - // 应用 HAVING 过滤 - var filteredResults []map[string]interface{} - for _, result := range finalResults { - if havingFilter.Evaluate(result) { - filteredResults = append(filteredResults, result) + if hasCaseExpression { + // HAVING条件包含CASE表达式,使用我们的表达式解析器 + expression, err := expr.NewExpression(s.config.Having) + if err != nil { + logger.Error("having filter error (CASE expression): %v", err) + } else { + // 应用 HAVING 过滤,使用CASE表达式计算器 + for _, result := range finalResults { + // 使用EvaluateWithNull方法以支持NULL值处理 + 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 限制