code: func (p *LogicalProjection) PruneColumns(parentUsedCols []*expression.Column) error {
  	child := p.children[0]
  	used, err := getUsedList(parentUsedCols, p.schema)
  	if err != nil {
  		return err
  	}
  
  	for i := len(used) - 1; i >= 0; i-- {
  		if !used[i] && !exprHasSetVar(p.Exprs[i]) {
  			p.schema.Columns = append(p.schema.Columns[:i], p.schema.Columns[i+1:]...)
  			p.Exprs = append(p.Exprs[:i], p.Exprs[i+1:]...)
  		}
  	}
  	// Prune TblID2Handle since that handle column may be pruned.
  	for k, cols := range p.schema.TblID2Handle {
  		if p.schema.ColumnIndex(cols[0]) == -1 {
  			delete(p.schema.TblID2Handle, k)
  		}
  	}
  	selfUsedCols := make([]*expression.Column, 0, len(p.Exprs))
  	selfUsedCols = expression.ExtractColumnsFromExpressions(selfUsedCols, p.Exprs, nil)
  	return child.PruneColumns(selfUsedCols)
  }
docs: // PruneColumns implements LogicalPlan interface.
  // If any expression has SetVar functions, we do not prune it.