func (s *testVisitorSuite) TestBase(c *C) { val := expression.Value{Val: 1} visitor := expression.NewIdentEvalVisitor() var exp expression.Expression exp = &expression.Between{Expr: val, Left: val, Right: val} exp.Accept(visitor) exp = expression.NewBinaryOperation(opcode.And, val, val) exp.Accept(visitor) exp, _ = expression.NewCall("avg", []expression.Expression{val}, true) exp.Accept(visitor) rows := [][]interface{}{{1}} sq := newMockSubQuery(rows, []string{"a"}) exp = expression.NewCompareSubQuery(opcode.EQ, val, sq, true) exp.Accept(visitor) exp = &expression.Default{Name: "a"} exp.Accept(visitor) exp = expression.NewExistsSubQuery(sq) exp.Accept(visitor) when := &expression.WhenClause{Expr: val, Result: val} exp = &expression.FunctionCase{ WhenClauses: []*expression.WhenClause{when}, Value: val, ElseClause: val, } exp.Accept(visitor) exp = &expression.FunctionCast{Expr: val, Tp: types.NewFieldType(mysql.TypeLong), FunctionType: expression.ConvertFunction} exp.Accept(visitor) exp = &expression.FunctionConvert{Expr: val, Charset: "utf8"} exp.Accept(visitor) exp = &expression.FunctionSubstring{StrExpr: expression.Value{Val: "string"}, Pos: expression.Value{Val: 0}, Len: val} exp.Accept(visitor) exp = &expression.IsNull{Expr: val} exp.Accept(visitor) exp = &expression.IsTruth{Expr: val} exp.Accept(visitor) exp = &expression.ParamMarker{Expr: val} exp.Accept(visitor) exp = &expression.PatternIn{Expr: val, List: []expression.Expression{val}} exp.Accept(visitor) exp = &expression.PatternLike{Expr: val, Pattern: val} exp.Accept(visitor) exp = &expression.PatternRegexp{Expr: val, Pattern: val} exp.Accept(visitor) exp = &expression.PExpr{Expr: val} exp.Accept(visitor) exp = &expression.Position{Name: "a"} exp.Accept(visitor) exp = &expression.Row{Values: []expression.Expression{val}} exp.Accept(visitor) exp = &expression.UnaryOperation{V: val} exp.Accept(visitor) exp = &expression.Values{CIStr: model.NewCIStr("a")} exp.Accept(visitor) exp = &expression.Variable{Name: "a"} exp.Accept(visitor) }
func (c *expressionConverter) compareSubquery(v *ast.CompareSubqueryExpr) { expr := c.exprMap[v.L] subquery := c.exprMap[v.R] oldCmpSubquery := expression.NewCompareSubQuery(v.Op, expr, subquery.(expression.SubQuery), v.All) c.exprMap[v] = oldCmpSubquery }
func (s *testCompSubQuerySuite) TestCompSubQuery(c *C) { tbl := []struct { lhs interface{} op opcode.Op rhs []interface{} all bool result interface{} // 0 for false, 1 for true, nil for nil. }{ // Test any subquery. {nil, opcode.EQ, []interface{}{1, 2}, false, nil}, {0, opcode.EQ, []interface{}{1, 2}, false, 0}, {0, opcode.EQ, []interface{}{1, 2, nil}, false, nil}, {1, opcode.EQ, []interface{}{1, 1}, false, 1}, {1, opcode.EQ, []interface{}{1, 1, nil}, false, 1}, {nil, opcode.NE, []interface{}{1, 2}, false, nil}, {1, opcode.NE, []interface{}{1, 2}, false, 1}, {1, opcode.NE, []interface{}{1, 2, nil}, false, 1}, {1, opcode.NE, []interface{}{1, 1}, false, 0}, {1, opcode.NE, []interface{}{1, 1, nil}, false, nil}, {nil, opcode.GT, []interface{}{1, 2}, false, nil}, {1, opcode.GT, []interface{}{1, 2}, false, 0}, {1, opcode.GT, []interface{}{1, 2, nil}, false, nil}, {2, opcode.GT, []interface{}{1, 2}, false, 1}, {2, opcode.GT, []interface{}{1, 2, nil}, false, 1}, {3, opcode.GT, []interface{}{1, 2}, false, 1}, {3, opcode.GT, []interface{}{1, 2, nil}, false, 1}, {nil, opcode.GE, []interface{}{1, 2}, false, nil}, {0, opcode.GE, []interface{}{1, 2}, false, 0}, {0, opcode.GE, []interface{}{1, 2, nil}, false, nil}, {1, opcode.GE, []interface{}{1, 2}, false, 1}, {1, opcode.GE, []interface{}{1, 2, nil}, false, 1}, {2, opcode.GE, []interface{}{1, 2}, false, 1}, {3, opcode.GE, []interface{}{1, 2}, false, 1}, {nil, opcode.LT, []interface{}{1, 2}, false, nil}, {0, opcode.LT, []interface{}{1, 2}, false, 1}, {0, opcode.LT, []interface{}{1, 2, nil}, false, 1}, {1, opcode.LT, []interface{}{1, 2}, false, 1}, {2, opcode.LT, []interface{}{1, 2}, false, 0}, {2, opcode.LT, []interface{}{1, 2, nil}, false, nil}, {3, opcode.LT, []interface{}{1, 2}, false, 0}, {nil, opcode.LE, []interface{}{1, 2}, false, nil}, {0, opcode.LE, []interface{}{1, 2}, false, 1}, {0, opcode.LE, []interface{}{1, 2, nil}, false, 1}, {1, opcode.LE, []interface{}{1, 2}, false, 1}, {2, opcode.LE, []interface{}{1, 2}, false, 1}, {3, opcode.LE, []interface{}{1, 2}, false, 0}, {3, opcode.LE, []interface{}{1, 2, nil}, false, nil}, // Test all subquery. {nil, opcode.EQ, []interface{}{1, 2}, true, nil}, {0, opcode.EQ, []interface{}{1, 2}, true, 0}, {0, opcode.EQ, []interface{}{1, 2, nil}, true, 0}, {1, opcode.EQ, []interface{}{1, 2}, true, 0}, {1, opcode.EQ, []interface{}{1, 2, nil}, true, 0}, {1, opcode.EQ, []interface{}{1, 1}, true, 1}, {1, opcode.EQ, []interface{}{1, 1, nil}, true, nil}, {nil, opcode.NE, []interface{}{1, 2}, true, nil}, {0, opcode.NE, []interface{}{1, 2}, true, 1}, {1, opcode.NE, []interface{}{1, 2, nil}, true, 0}, {1, opcode.NE, []interface{}{1, 1}, true, 0}, {1, opcode.NE, []interface{}{1, 1, nil}, true, 0}, {nil, opcode.GT, []interface{}{1, 2}, true, nil}, {1, opcode.GT, []interface{}{1, 2}, true, 0}, {1, opcode.GT, []interface{}{1, 2, nil}, true, 0}, {2, opcode.GT, []interface{}{1, 2}, true, 0}, {2, opcode.GT, []interface{}{1, 2, nil}, true, 0}, {3, opcode.GT, []interface{}{1, 2}, true, 1}, {3, opcode.GT, []interface{}{1, 2, nil}, true, nil}, {nil, opcode.GE, []interface{}{1, 2}, true, nil}, {0, opcode.GE, []interface{}{1, 2}, true, 0}, {0, opcode.GE, []interface{}{1, 2, nil}, true, 0}, {1, opcode.GE, []interface{}{1, 2}, true, 0}, {1, opcode.GE, []interface{}{1, 2, nil}, true, 0}, {2, opcode.GE, []interface{}{1, 2}, true, 1}, {3, opcode.GE, []interface{}{1, 2}, true, 1}, {3, opcode.GE, []interface{}{1, 2, nil}, true, nil}, {nil, opcode.LT, []interface{}{1, 2}, true, nil}, {0, opcode.LT, []interface{}{1, 2}, true, 1}, {0, opcode.LT, []interface{}{1, 2, nil}, true, nil}, {1, opcode.LT, []interface{}{1, 2}, true, 0}, {2, opcode.LT, []interface{}{1, 2}, true, 0}, {2, opcode.LT, []interface{}{1, 2, nil}, true, 0}, {3, opcode.LT, []interface{}{1, 2}, true, 0}, {nil, opcode.LE, []interface{}{1, 2}, true, nil}, {0, opcode.LE, []interface{}{1, 2}, true, 1}, {0, opcode.LE, []interface{}{1, 2, nil}, true, nil}, {1, opcode.LE, []interface{}{1, 2}, true, 1}, {2, opcode.LE, []interface{}{1, 2}, true, 0}, {3, opcode.LE, []interface{}{1, 2}, true, 0}, {3, opcode.LE, []interface{}{1, 2, nil}, true, 0}, } ctx := mock.NewContext() for _, t := range tbl { lhs := convert(t.lhs) rhs := make([][]interface{}, 0, len(t.rhs)) for _, v := range t.rhs { rhs = append(rhs, []interface{}{convert(v)}) } sq := newMockSubQuery(rhs, []string{"c"}) expr := expression.NewCompareSubQuery(t.op, expression.Value{Val: lhs}, sq, t.all) c.Assert(expr.IsStatic(), IsFalse) str := expr.String() c.Assert(len(str), Greater, 0) v, err := expr.Eval(ctx, nil) c.Assert(err, IsNil) switch x := t.result.(type) { case nil: c.Assert(v, IsNil) case int: val, err := types.ToBool(v) c.Assert(err, IsNil) c.Assert(val, Equals, int64(x)) } } // Test error. sq := newMockSubQuery([][]interface{}{{1, 2}}, []string{"c1", "c2"}) expr := expression.NewCompareSubQuery(opcode.EQ, expression.Value{Val: 1}, sq, true) _, err := expr.Eval(ctx, nil) c.Assert(err, NotNil) expr = expression.NewCompareSubQuery(opcode.EQ, expression.Value{Val: 1}, sq, false) _, err = expr.Eval(ctx, nil) c.Assert(err, NotNil) }