func (s *testEvaluatorSuite) TestEvaluatedFlag(c *C) { l := ast.NewValueExpr(int64(1)) r := ast.NewValueExpr(int64(2)) b := &ast.BinaryOperationExpr{L: l, R: r, Op: opcode.Plus} ast.SetFlag(b) c.Assert(ast.IsPreEvaluable(b), Equals, true) d, err := Eval(s.ctx, b) c.Assert(ast.IsEvaluated(b), Equals, true) c.Assert(err, IsNil) c.Assert(d, testutil.DatumEquals, types.NewIntDatum(3)) funcCall := &ast.FuncCallExpr{ FnName: model.NewCIStr("abs"), Args: []ast.ExprNode{ast.NewValueExpr(int(-1))}, } b = &ast.BinaryOperationExpr{L: funcCall, R: r, Op: opcode.Plus} ast.ResetEvaluatedFlag(b) ast.SetFlag(b) c.Assert(ast.IsPreEvaluable(b), Equals, true) d, err = Eval(s.ctx, b) c.Assert(ast.IsEvaluated(b), Equals, false) c.Assert(err, IsNil) c.Assert(d, testutil.DatumEquals, types.NewIntDatum(3)) rf := &ast.ResultField{Expr: ast.NewValueExpr(int64(1))} colExpr := &ast.ColumnNameExpr{Refer: rf} b = &ast.BinaryOperationExpr{L: colExpr, R: r, Op: opcode.Plus} ast.ResetEvaluatedFlag(b) ast.SetFlag(b) c.Assert(ast.IsPreEvaluable(b), Equals, false) d, err = Eval(s.ctx, b) c.Assert(ast.IsEvaluated(b), Equals, false) c.Assert(err, IsNil) c.Assert(d, testutil.DatumEquals, types.NewIntDatum(3)) }
// Build builds a prepared statement into an executor. func (e *ExecuteExec) Build() error { vars := variable.GetSessionVars(e.Ctx) if e.Name != "" { e.ID = vars.PreparedStmtNameToID[e.Name] } v := vars.PreparedStmts[e.ID] if v == nil { return ErrStmtNotFound } prepared := v.(*Prepared) if len(prepared.Params) != len(e.UsingVars) { return ErrWrongParamCount } for i, usingVar := range e.UsingVars { val, err := evaluator.Eval(e.Ctx, usingVar) if err != nil { return errors.Trace(err) } prepared.Params[i].SetDatum(val) } ast.ResetEvaluatedFlag(prepared.Stmt) if prepared.SchemaVersion != e.IS.SchemaMetaVersion() { // If the schema version has changed we need to prepare it again, // if this time it failed, the real reason for the error is schema changed. err := plan.PrepareStmt(e.IS, e.Ctx, prepared.Stmt) if err != nil { return ErrSchemaChanged.Gen("Schema change casued error: %s", err.Error()) } prepared.SchemaVersion = e.IS.SchemaMetaVersion() } sb := &subqueryBuilder{is: e.IS} p, err := plan.Optimize(e.Ctx, prepared.Stmt, sb, e.IS) if err != nil { return errors.Trace(err) } b := newExecutorBuilder(e.Ctx, e.IS) stmtExec := b.build(p) if b.err != nil { return errors.Trace(b.err) } e.StmtExec = stmtExec e.Stmt = prepared.Stmt return nil }
func (s *testEvaluatorSuite) TestCaseWhen(c *C) { defer testleak.AfterTest(c)() cases := []testCase{ { exprStr: "case 1 when 1 then 'str1' when 2 then 'str2' end", resultStr: "str1", }, { exprStr: "case 2 when 1 then 'str1' when 2 then 'str2' end", resultStr: "str2", }, { exprStr: "case 3 when 1 then 'str1' when 2 then 'str2' end", resultStr: "<nil>", }, { exprStr: "case 4 when 1 then 'str1' when 2 then 'str2' else 'str3' end", resultStr: "str3", }, } s.runTests(c, cases) // When expression value changed, result set back to null. valExpr := ast.NewValueExpr(1) whenClause := &ast.WhenClause{Expr: ast.NewValueExpr(1), Result: ast.NewValueExpr(1)} caseExpr := &ast.CaseExpr{ Value: valExpr, WhenClauses: []*ast.WhenClause{whenClause}, } ctx := mock.NewContext() v, err := Eval(ctx, caseExpr) c.Assert(err, IsNil) c.Assert(v, testutil.DatumEquals, types.NewDatum(int64(1))) valExpr.SetValue(4) ast.ResetEvaluatedFlag(caseExpr) v, err = Eval(ctx, caseExpr) c.Assert(err, IsNil) c.Assert(v.Kind(), Equals, types.KindNull) }