code: func (p *Union) PredicatePushDown(predicates []expression.Expression) (ret []expression.Expression, retPlan LogicalPlan, err error) {
  	retPlan = p
  	for _, proj := range p.children {
  		newExprs := make([]expression.Expression, 0, len(predicates))
  		for _, cond := range predicates {
  			newCond := expression.ColumnSubstitute(cond, p.GetSchema(), expression.Column2Exprs(proj.GetSchema().Columns))
  			newExprs = append(newExprs, newCond)
  		}
  		retCond, _, err := proj.(LogicalPlan).PredicatePushDown(newExprs)
  		if err != nil {
  			return nil, nil, errors.Trace(err)
  		}
  		if len(retCond) != 0 {
  			addSelection(p, proj.(LogicalPlan), retCond, p.allocator)
  		}
  	}
  	return
  }
docs: // PredicatePushDown implements LogicalPlan PredicatePushDown interface.