code: func (p *Aggregation) convert2PhysicalPlan(prop *requiredProperty) (*physicalPlanInfo, error) {
  	planInfo, err := p.getPlanInfo(prop)
  	if err != nil {
  		return nil, errors.Trace(err)
  	}
  	if planInfo != nil {
  		return planInfo, nil
  	}
  	limit := prop.limit
  	if len(prop.props) == 0 {
  		planInfo, err = p.convert2PhysicalPlanHash()
  		if err != nil {
  			return nil, errors.Trace(err)
  		}
  	}
  	streamInfo, err := p.convert2PhysicalPlanStream(removeLimit(prop))
  	if planInfo == nil || streamInfo.cost < planInfo.cost {
  		planInfo = streamInfo
  	}
  	planInfo = enforceProperty(limitProperty(limit), planInfo)
  	err = p.storePlanInfo(prop, planInfo)
  	return planInfo, errors.Trace(err)
  }
docs: // convert2PhysicalPlan implements the LogicalPlan convert2PhysicalPlan interface.