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 }
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 }