code: func (la *LogicalAggregation) PredicatePushDown(predicates []expression.Expression) (ret []expression.Expression, retPlan LogicalPlan) {
  	var condsToPush []expression.Expression
  	exprsOriginal := make([]expression.Expression, 0, len(la.AggFuncs))
  	for _, fun := range la.AggFuncs {
  		exprsOriginal = append(exprsOriginal, fun.Args[0])
  	}
  	for _, cond := range predicates {
  		switch cond.(type) {
  		case *expression.Constant:
  			condsToPush = append(condsToPush, cond)
  			// Consider SQL list "select sum(b) from t group by a having 1=0". "1=0" is a constant predicate which should be
  			// retained and pushed down at the same time. Because we will get a wrong query result that contains one column
  			// with value 0 rather than an empty query result.
  			ret = append(ret, cond)
  		case *expression.ScalarFunction:
  			extractedCols := expression.ExtractColumns(cond)
  			ok := true
  			for _, col := range extractedCols {
  				if la.getGbyColIndex(col) == -1 {
  					ok = false
  					break
  				}
  			}
  			if ok {
  				newFunc := expression.ColumnSubstitute(cond, la.Schema(), exprsOriginal)
  				condsToPush = append(condsToPush, newFunc)
  			} else {
  				ret = append(ret, cond)
  			}
  		default:
  			ret = append(ret, cond)
  		}
  	}
  	la.baseLogicalPlan.PredicatePushDown(condsToPush)
  	return ret, la
  }
docs: // PredicatePushDown implements LogicalPlan PredicatePushDown interface.