示例#1
0
文件: groupby.go 项目: H0bby/tidb
func (r *GroupByDefaultPlan) evalAggFields(ctx context.Context, out []interface{},
	m map[interface{}]interface{}, in []interface{}) error {

	m[expression.ExprEvalIdentReferFunc] = func(name string, scope int, index int) (interface{}, error) {
		if scope == expression.IdentReferFromTable {
			return in[index], nil
		} else if scope == expression.IdentReferSelectList {
			return out[index], nil
		}

		// try to find in outer query
		return getIdentValueFromOuterQuery(ctx, name)
	}

	// Eval aggregate field results in ctx
	for i := range r.AggFields {
		// we must evaluate aggregate function only, e.g, select col1 + count(*) in (count(*)),
		// we cannot evaluate it directly here, because col1 + count(*) returns nil before AggDone phase,
		// so we don't evaluate count(*) in In expression, and will get an invalid data in AggDone phase for it.
		// mention all aggregate functions
		// TODO: optimize, we can get these aggregate functions only once and reuse
		aggs, err := expression.MentionedAggregateFuncs(r.Fields[i].Expr)
		if err != nil {
			return errors.Trace(err)
		}
		for _, agg := range aggs {
			if _, err := agg.Eval(ctx, m); err != nil {
				return err
			}
		}
	}

	return nil
}
示例#2
0
func (r *GroupByDefaultPlan) evalAggFields(ctx context.Context, out []interface{},
	m map[interface{}]interface{}, in []interface{}) error {
	// Eval aggregate field results in ctx
	for i := range r.AggFields {
		if i < r.HiddenFieldOffset {
			m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
				v, err := GetIdentValue(name, r.Src.GetFields(), in, field.DefaultFieldFlag)
				if err == nil {
					return v, nil
				}

				// try to find in outer query
				return getIdentValueFromOuterQuery(ctx, name)
			}
		} else {
			// having may contain aggregate function and we will add it to hidden field,
			// and this field can retrieve the data in select list, e.g.
			// 	select c1 as a from t having count(a) = 1
			// because all the select list data is generated before, so we can get it
			// when handling hidden field.
			m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
				v, err := GetIdentValue(name, r.Src.GetFields(), in, field.DefaultFieldFlag)
				if err == nil {
					return v, nil
				}

				// if we can not find in table, we will try to find in un-hidden select list
				// only hidden field can use this
				v, err = r.getFieldValueByName(name, out)
				if err == nil {
					return v, nil
				}

				// try to find in outer query
				return getIdentValueFromOuterQuery(ctx, name)
			}
		}

		// we must evaluate aggregate function only, e.g, select col1 + count(*) in (count(*)),
		// we cannot evaluate it directly here, because col1 + count(*) returns nil before AggDone phase,
		// so we don't evaluate count(*) in In expression, and will get an invalid data in AggDone phase for it.
		// mention all aggregate functions
		// TODO: optimize, we can get these aggregate functions only once and reuse
		aggs, err := expression.MentionedAggregateFuncs(r.Fields[i].Expr)
		if err != nil {
			return errors.Trace(err)
		}
		for _, agg := range aggs {
			if _, err := agg.Eval(ctx, m); err != nil {
				return err
			}
		}
	}

	return nil
}