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