示例#1
0
func getIdentValueFromOuterQuery(ctx context.Context, name string) (interface{}, error) {
	s := getRowStack(ctx)
	if s == nil {
		return nil, errors.Errorf("unknown field %s", name)
	}

	// The top is current RowStack, use its last.
	n := len(s.items) - 2

	var (
		v   interface{}
		err error
	)

	for ; n >= 0; n-- {
		t := s.items[n]

		// first try to get from outer table reference.
		if t.FromData != nil {
			v, err = GetIdentValue(name, t.FromDataFields, t.FromData)
			if err == nil {
				// tell current subquery using outer query
				subquery.SetOuterQueryUsed(ctx)
				return v, nil
			}
		}

		// then try to get from outer select list.
		if t.OutData != nil {
			v, err = GetIdentValue(name, t.OutDataFields, t.OutData)
			if err == nil {
				// tell current subquery using outer query
				subquery.SetOuterQueryUsed(ctx)
				return v, nil
			}
		}
	}

	return nil, errors.Errorf("unknown field %s", name)
}
示例#2
0
func (s *testSubQuerySuite) TestSubQuery(c *C) {
	e := &subquery.SubQuery{
		Val: 1,
	}

	ctx := mock.NewContext()
	c.Assert(e.IsStatic(), IsFalse)

	str := e.String()
	c.Assert(str, Equals, "")

	ec := e.Clone()

	v, err := ec.Eval(ctx, nil)
	c.Assert(err, IsNil)
	c.Assert(v, Equals, 1)

	e2, ok := ec.(*subquery.SubQuery)
	c.Assert(ok, IsTrue)

	e2 = newMockSubQuery([][]interface{}{{1}}, []string{"id"})

	vv, err := e2.Eval(ctx, nil)
	c.Assert(err, IsNil)
	c.Assert(vv, Equals, 1)

	e2.SetValue(nil)
	vv, err = e2.Eval(ctx, nil)
	c.Assert(err, IsNil)
	c.Assert(vv, Equals, 1)

	e2 = newMockSubQuery([][]interface{}{{1, 2}}, []string{"id", "name"})

	vv, err = e2.Eval(ctx, nil)
	c.Assert(err, IsNil)
	c.Assert(vv, DeepEquals, []interface{}{1, 2})

	e2 = newMockSubQuery([][]interface{}{{1}, {2}}, []string{"id"})

	_, err = e2.Eval(ctx, nil)
	c.Assert(err, NotNil)

	str = e2.String()
	c.Assert(len(str), Greater, 0)

	e2 = newMockSubQuery([][]interface{}{{1, 2}}, []string{"id", "name"})

	count, err := e2.ColumnCount(nil)
	c.Assert(err, IsNil)
	c.Assert(count, Equals, 2)

	count, err = e2.ColumnCount(nil)
	c.Assert(err, IsNil)
	c.Assert(count, Equals, 2)

	e3 := newMockSubQuery([][]interface{}{{1, 2}}, []string{"id", "name"})

	e2.Push(ctx)
	e3.Push(ctx)

	c.Assert(e2.UseOuter, IsFalse)
	c.Assert(e3.UseOuter, IsFalse)
	subquery.SetOuterQueryUsed(ctx)
	c.Assert(e2.UseOuterQuery, IsTrue)
	c.Assert(e3.UseOuterQuery, IsTrue)
	err = e2.Pop(ctx)
	c.Assert(err, NotNil)

	err = e3.Pop(ctx)
	subquery.SetOuterQueryUsed(ctx)

	err = e2.Pop(ctx)
	c.Assert(err, IsNil)

	err = e2.Pop(ctx)
	c.Assert(err, NotNil)

	subquery.SetOuterQueryUsed(ctx)

	c.Assert(len(subquery.SubQueryStackKey.String()), Greater, 0)
}