func (s *testEvalSuite) TestEvalCoalesce(c *C) { colID := int64(1) row := make(map[int64]types.Datum) row[colID] = types.NewIntDatum(100) xevaluator := &Evaluator{Row: row} nullDatum := types.Datum{} nullDatum.SetNull() notNullDatum := types.NewStringDatum("not-null") cases := []struct { expr *tipb.Expr result types.Datum }{ { expr: buildExpr(tipb.ExprType_Coalesce, nullDatum, nullDatum, nullDatum), result: nullDatum, }, { expr: buildExpr(tipb.ExprType_Coalesce, nullDatum, notNullDatum, nullDatum), result: notNullDatum, }, { expr: buildExpr(tipb.ExprType_Coalesce, nullDatum, notNullDatum, types.NewStringDatum("not-null-2"), nullDatum), result: notNullDatum, }, } for _, ca := range cases { result, err := xevaluator.Eval(ca.expr) c.Assert(err, IsNil) c.Assert(result.Kind(), Equals, ca.result.Kind()) cmp, err := result.CompareDatum(xevaluator.sc, ca.result) c.Assert(err, IsNil) c.Assert(cmp, Equals, 0) } }
// evalXor computes result of (X XOR Y). func (e *Evaluator) evalXor(leftBool, rightBool int64) (types.Datum, error) { var d types.Datum if leftBool == compareResultNull || rightBool == compareResultNull { d.SetNull() return d, nil } if leftBool == rightBool { d.SetInt64(0) return d, nil } d.SetInt64(1) return d, nil }
func (e *Evaluator) evalOr(expr *tipb.Expr) (types.Datum, error) { leftBool, rightBool, err := e.evalTwoBoolChildren(expr) if err != nil { return types.Datum{}, errors.Trace(err) } var d types.Datum if leftBool == 1 || rightBool == 1 { d.SetInt64(1) return d, nil } if leftBool == compareResultNull || rightBool == compareResultNull { d.SetNull() return d, nil } d.SetInt64(0) return d, nil }
// See https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date func builtinStrToDate(args []types.Datum, _ context.Context) (types.Datum, error) { date := args[0].GetString() format := args[1].GetString() var ( d types.Datum t types.Time ) succ := t.StrToDate(date, format) if !succ { d.SetNull() return d, nil } d.SetMysqlTime(t) return d, nil }
func (s *testEvalSuite) TestEvalCaseWhen(c *C) { colID := int64(1) xevaluator := NewEvaluator(new(variable.StatementContext)) xevaluator.Row[colID] = types.NewIntDatum(100) trueCond := types.NewIntDatum(1) falseCond := types.NewIntDatum(0) nullCond := types.Datum{} nullCond.SetNull() cases := []struct { expr *tipb.Expr result types.Datum }{ { expr: buildExpr(tipb.ExprType_Case, falseCond, types.NewStringDatum("case1"), trueCond, types.NewStringDatum("case2"), trueCond, types.NewStringDatum("case3")), result: types.NewStringDatum("case2"), }, { expr: buildExpr(tipb.ExprType_Case, falseCond, types.NewStringDatum("case1"), falseCond, types.NewStringDatum("case2"), falseCond, types.NewStringDatum("case3"), types.NewStringDatum("Else")), result: types.NewStringDatum("Else"), }, { expr: buildExpr(tipb.ExprType_Case, falseCond, types.NewStringDatum("case1"), falseCond, types.NewStringDatum("case2"), falseCond, types.NewStringDatum("case3")), result: types.Datum{}, }, { expr: buildExpr(tipb.ExprType_Case, buildExpr(tipb.ExprType_Case, falseCond, types.NewIntDatum(0), trueCond, types.NewIntDatum(1), ), types.NewStringDatum("nested case when"), falseCond, types.NewStringDatum("case1"), trueCond, types.NewStringDatum("case2"), trueCond, types.NewStringDatum("case3")), result: types.NewStringDatum("nested case when"), }, { expr: buildExpr(tipb.ExprType_Case, nullCond, types.NewStringDatum("case1"), falseCond, types.NewStringDatum("case2"), trueCond, types.NewStringDatum("case3")), result: types.NewStringDatum("case3"), }, } for _, ca := range cases { result, err := xevaluator.Eval(ca.expr) c.Assert(err, IsNil) c.Assert(result.Kind(), Equals, ca.result.Kind()) cmp, err := result.CompareDatum(xevaluator.sc, ca.result) c.Assert(err, IsNil) c.Assert(cmp, Equals, 0) } }