code: func (la *LogicalAggregation) PruneColumns(parentUsedCols []*expression.Column) error {
  	child := la.children[0]
  	used, err := getUsedList(parentUsedCols, la.Schema())
  	if err != nil {
  		return err
  	}
  
  	for i := len(used) - 1; i >= 0; i-- {
  		if !used[i] {
  			la.schema.Columns = append(la.schema.Columns[:i], la.schema.Columns[i+1:]...)
  			la.AggFuncs = append(la.AggFuncs[:i], la.AggFuncs[i+1:]...)
  		}
  	}
  	var selfUsedCols []*expression.Column
  	for _, aggrFunc := range la.AggFuncs {
  		selfUsedCols = expression.ExtractColumnsFromExpressions(selfUsedCols, aggrFunc.Args, nil)
  	}
  	if len(la.GroupByItems) > 0 {
  		for i := len(la.GroupByItems) - 1; i >= 0; i-- {
  			cols := expression.ExtractColumns(la.GroupByItems[i])
  			if len(cols) == 0 {
  				la.GroupByItems = append(la.GroupByItems[:i], la.GroupByItems[i+1:]...)
  			} else {
  				selfUsedCols = append(selfUsedCols, cols...)
  			}
  		}
  		// If all the group by items are pruned, we should add a constant 1 to keep the correctness.
  		// Because `select count(*) from t` is different from `select count(*) from t group by 1`.
  		if len(la.GroupByItems) == 0 {
  			la.GroupByItems = []expression.Expression{expression.One}
  		}
  	}
  	return child.PruneColumns(selfUsedCols)
  }
docs: // PruneColumns implements LogicalPlan interface.