Пример #1
0
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))
}
Пример #2
0
// 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
}
Пример #3
0
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)
}