code: func (p *LogicalProjection) PredicatePushDown(predicates []expression.Expression) (ret []expression.Expression, retPlan LogicalPlan) {
  	canBePushed := make([]expression.Expression, 0, len(predicates))
  	canNotBePushed := make([]expression.Expression, 0, len(predicates))
  	for _, cond := range predicates {
  		newFilter := expression.ColumnSubstitute(cond, p.Schema(), p.Exprs)
  		if !expression.HasGetSetVarFunc(newFilter) {
  			canBePushed = append(canBePushed, expression.ColumnSubstitute(cond, p.Schema(), p.Exprs))
  		} else {
  			canNotBePushed = append(canNotBePushed, cond)
  		}
  	}
  	remained, child := p.baseLogicalPlan.PredicatePushDown(canBePushed)
  	return append(remained, canNotBePushed...), child
  }
docs: // PredicatePushDown implements LogicalPlan PredicatePushDown interface.