code: def _need_prune(self, op: OperandType) -> bool:
      data_source_node = self._graph.predecessors(op.outputs[0])[0]
      input_can_be_pruned = isinstance(
          data_source_node.op, ColumnPruneSupportedDataSourceMixin
      )
      if (
          input_can_be_pruned
          and data_source_node not in self._graph.results
          and op.col_names is not None
      ):
          selected_columns = self._get_selected_columns(op)
          if (
              not isinstance(op.outputs[0], CHUNK_TYPE)
              and not selected_columns
          ):
              # no columns selected, skip
              return False
          return True
      return False
  
file_path: mars/mars/optimization/logical/common/column_pruning.py
imports: from abc import ABCMeta, abstractmethod
  from typing import Any, List
  from ..core import OperandBasedOptimizationRule, OptimizationRecord, OptimizationRecordType
  from ....core import OperandType, TileableType, CHUNK_TYPE
  from ....dataframe.datasource.core import ColumnPruneSupportedDataSourceMixin
  from ....dataframe.utils import parse_index
  from ....utils import implements
label_desc: Use image node_id 1 for calling the GetitemPruneDataSource obj's underlying member method code with example usage: obj._need_prune(op) and returns: False, True, False