// CheckAndUpdateSelectList checks order by fields validity and set hidden fields to selectList. func (r *OrderByRset) CheckAndUpdateSelectList(selectList *plans.SelectList, tableFields []*field.ResultField) error { for i, v := range r.By { if expressions.ContainAggregateFunc(v.Expr) { expr, err := selectList.UpdateAggFields(v.Expr, tableFields) if err != nil { return errors.Errorf("%s in 'order clause'", err.Error()) } r.By[i].Expr = expr } else { names := expressions.MentionedColumns(v.Expr) for _, name := range names { // try to find in select list // TODO: mysql has confused result for this, see #555. // now we use select list then order by, later we should make it easier. if field.ContainFieldName(name, selectList.ResultFields, field.CheckFieldFlag) { // check ambiguous fields, like `select c1 as c2, c2 from t order by c2`. if err := field.CheckAmbiguousField(name, selectList.ResultFields, field.DefaultFieldFlag); err != nil { return errors.Errorf("Column '%s' in order statement is ambiguous", name) } continue } if !selectList.CloneHiddenField(name, tableFields) { return errors.Errorf("Unknown column '%s' in 'order clause'", name) } } } } return nil }
// CheckAndUpdateSelectList checks having fields validity and set hidden fields to selectList. func (r *HavingRset) CheckAndUpdateSelectList(selectList *plans.SelectList, groupBy []expression.Expression, tableFields []*field.ResultField) error { if err := expressions.CheckOneColumn(r.Expr); err != nil { return errors.Trace(err) } if expressions.ContainAggregateFunc(r.Expr) { expr, err := selectList.UpdateAggFields(r.Expr, tableFields) if err != nil { return errors.Errorf("%s in 'having clause'", err.Error()) } r.Expr = expr } else { // having can only contain group by column and select list, e.g, // `select c1 from t group by c2 having c3 > 0` is invalid, // because c3 is not in group by and select list. names := expressions.MentionedColumns(r.Expr) for _, name := range names { found := false // check name whether in select list. // notice that `select c1 as c2 from t group by c1, c2, c3 having c2 > c3`, // will use t.c2 not t.c1 here. if field.ContainFieldName(name, selectList.ResultFields, field.OrgFieldNameFlag) { continue } if field.ContainFieldName(name, selectList.ResultFields, field.FieldNameFlag) { if field.ContainFieldName(name, tableFields, field.OrgFieldNameFlag) { selectList.CloneHiddenField(name, tableFields) } continue } // check name whether in group by. // group by must only have column name, e.g, // `select c1 from t group by c2 having c2 > 0` is valid, // but `select c1 from t group by c2 + 1 having c2 > 0` is invalid. for _, by := range groupBy { if !field.CheckFieldsEqual(name, by.String()) { continue } // if name is not in table fields, it will get an unknown field error in GroupByRset, // so no need to check return value. selectList.CloneHiddenField(name, tableFields) found = true break } if !found { return errors.Errorf("Unknown column '%s' in 'having clause'", name) } } } return nil }
// CheckAggregate will check whether order by has aggregate function or not, // if has, we will add it to select list hidden field. func (r *HavingRset) CheckAggregate(selectList *plans.SelectList) error { if expression.ContainAggregateFunc(r.Expr) { expr, err := selectList.UpdateAggFields(r.Expr) if err != nil { return errors.Errorf("%s in 'having clause'", err.Error()) } r.Expr = expr } return nil }
// CheckAggregate will check whether order by has aggregate function or not, // if has, we will add it to select list hidden field. func (r *OrderByRset) CheckAggregate(selectList *plans.SelectList) error { for i, v := range r.By { if expression.ContainAggregateFunc(v.Expr) { expr, err := selectList.UpdateAggFields(v.Expr) if err != nil { return errors.Errorf("%s in 'order clause'", err.Error()) } r.By[i].Expr = expr } } return nil }
// CheckAndUpdateSelectList checks order by fields validity and set hidden fields to selectList. func (r *OrderByRset) CheckAndUpdateSelectList(selectList *plans.SelectList, tableFields []*field.ResultField) error { for i, v := range r.By { if expression.ContainAggregateFunc(v.Expr) { expr, err := selectList.UpdateAggFields(v.Expr, tableFields) if err != nil { return errors.Errorf("%s in 'order clause'", err.Error()) } r.By[i].Expr = expr } else { if _, err := selectList.CheckReferAmbiguous(v.Expr); err != nil { return errors.Errorf("Column '%s' in order statement is ambiguous", v.Expr) } // TODO: check more ambiguous case // Order by ambiguous rule: // select c1 as a, c2 as a from t order by a is ambiguous // select c1 as a, c2 as a from t order by a + 1 is ambiguous // select c1 as c2, c2 from t order by c2 is ambiguous // select c1 as c2, c2 from t order by c2 + 1 is ambiguous // TODO: use vistor to refactor all and combine following plan check. names := expression.MentionedColumns(v.Expr) for _, name := range names { // try to find in select list // TODO: mysql has confused result for this, see #555. // now we use select list then order by, later we should make it easier. if field.ContainFieldName(name, selectList.ResultFields, field.CheckFieldFlag) { continue } if !selectList.CloneHiddenField(name, tableFields) { return errors.Errorf("Unknown column '%s' in 'order clause'", name) } } } } return nil }