diff --git a/pkg/sql/plan2/build_expr.go b/pkg/sql/plan2/build_expr.go index 797b5db61e1b0587a43b5806acc56c9092482e41..24a2fa8fe57ddae9f0a60e1d4ff4df9f1c1fdab8 100644 --- a/pkg/sql/plan2/build_expr.go +++ b/pkg/sql/plan2/build_expr.go @@ -229,62 +229,57 @@ func buildCastExpr(astExpr *tree.CastExpr, ctx CompilerContext, query *Query, no func buildCaseExpr(astExpr *tree.CaseExpr, ctx CompilerContext, query *Query, node *Node, binderCtx *BinderContext, needAgg bool) (expr *Expr, isAgg bool, err error) { var args []*Expr + var caseExpr *Expr if astExpr.Expr != nil { - caseExpr, _, err := buildExpr(astExpr.Expr, ctx, query, node, binderCtx, needAgg) + caseExpr, _, err = buildExpr(astExpr.Expr, ctx, query, node, binderCtx, needAgg) if err != nil { return nil, false, err } - args = append(args, caseExpr) } isAgg = true - whenList := make([]*Expr, len(astExpr.Whens)) - for idx, whenExpr := range astExpr.Whens { - exprs := make([]*Expr, 2) - expr, paramIsAgg, err := buildExpr(whenExpr.Cond, ctx, query, node, binderCtx, needAgg) + for _, whenExpr := range astExpr.Whens { + condExpr, paramIsAgg, err := buildExpr(whenExpr.Cond, ctx, query, node, binderCtx, needAgg) if err != nil { return nil, false, err } isAgg = isAgg && paramIsAgg - exprs[0] = expr - expr, paramIsAgg, err = buildExpr(whenExpr.Val, ctx, query, node, binderCtx, needAgg) + if caseExpr != nil { + // rewrite "case col when 1 then '1' else '2'" to "case when col=1 then '1' else '2'" + condExpr, _, err = getFunctionExprByNameAndPlanExprs("=", []*Expr{caseExpr, condExpr}) + if err != nil { + return nil, false, err + } + } + args = append(args, condExpr) + + valExpr, paramIsAgg, err := buildExpr(whenExpr.Val, ctx, query, node, binderCtx, needAgg) if err != nil { return nil, false, err } isAgg = isAgg && paramIsAgg - exprs[1] = expr - - whenList[idx] = &Expr{ - Expr: &plan.Expr_List{ - List: &plan.ExprList{ - List: exprs, - }, - }, - Typ: &plan.Type{ - Id: plan.Type_TUPLE, - }, - } - } - whenExpr := &Expr{ - Expr: &plan.Expr_List{ - List: &plan.ExprList{ - List: whenList, - }, - }, - Typ: &plan.Type{ - Id: plan.Type_TUPLE, - }, + args = append(args, valExpr) } - args = append(args, whenExpr) if astExpr.Else != nil { - elseExpr, paramIsAgg, err := buildExpr(astExpr.Else, ctx, query, node, binderCtx, needAgg) + elseExpr, _, err := buildExpr(astExpr.Else, ctx, query, node, binderCtx, needAgg) if err != nil { return nil, false, err } - isAgg = isAgg && paramIsAgg args = append(args, elseExpr) + } else { + args = append(args, &Expr{ + Expr: &plan.Expr_C{ + C: &Const{ + Isnull: true, + }, + }, + Typ: &plan.Type{ + Id: plan.Type_ANY, + Nullable: true, + }, + }) } return getFunctionExprByNameAndPlanExprs("case", args) }