src/executor/seq_scan_executor.cpp
bool SeqScanExecutor::DExecute() {
  // Scanning over a logical tile.
  if (children_.size() == 1 &&
      //There will be a child node on the create index scenario,
      //but we don't want to use this execution flow
      !(GetRawNode()->GetChildren().size() > 0 &&
        GetRawNode()->GetChildren()[0].get()->GetPlanNodeType() ==
            PlanNodeType::CREATE &&
        ((planner::CreatePlan *)GetRawNode()->GetChildren()[0].get())
                ->GetCreateType() == CreateType::INDEX)) {
    // FIXME Check all requirements for children_.size() == 0 case.
    LOG_TRACE("Seq Scan executor :: 1 child ");

    PL_ASSERT(target_table_ == nullptr);
    PL_ASSERT(column_ids_.size() == 0);

    while (children_[0]->Execute()) {
      std::unique_ptr<LogicalTile> tile(children_[0]->GetOutput());

      if (predicate_ != nullptr) {
        // Invalidate tuples that don't satisfy the predicate.
        for (oid_t tuple_id : *tile) {
          expression::ContainerTuple<LogicalTile> tuple(tile.get(), tuple_id);
          auto eval = predicate_->Evaluate(&tuple, nullptr, executor_context_);
          if (eval.IsFalse()) {
            // if (predicate_->Evaluate(&tuple, nullptr, executor_context_)
            //        .IsFalse()) {
            tile->RemoveVisibility(tuple_id);
          }
        }
      }

      if (0 == tile->GetTupleCount()) {  // Avoid returning empty tiles
        continue;
      }

      /* Hopefully we needn't do projections here */
      SetOutput(tile.release());
      return true;
    }
    return false;
  }
  // Scanning a table
  else if (children_.size() == 0 ||
           //If we are creating an index, there will be a child
           (children_.size() == 1 &&
            //This check is only needed to pass seq_scan_test
            //unless it is possible to add a executor child
            //without a corresponding plan.
            GetRawNode()->GetChildren().size() > 0 &&
            //Check if the plan is what we actually expect.
            GetRawNode()->GetChildren()[0].get()->GetPlanNodeType() ==
                PlanNodeType::CREATE &&
            //If it is, confirm it is for indexes
            ((planner::CreatePlan *)GetRawNode()->GetChildren()[0].get())
                    ->GetCreateType() == CreateType::INDEX)) {
    LOG_TRACE("Seq Scan executor :: 0 child ");

    PL_ASSERT(target_table_ != nullptr);
    PL_ASSERT(column_ids_.size() > 0);
    if (children_.size() > 0 && !index_done_) {
      children_[0]->Execute();
      //This stops continuous executions due to
      //a parent and avoids multiple creations
      //of the same index.
      index_done_ = true;
    }
    // Force to use occ txn manager if dirty read is forbidden
    concurrency::TransactionManager &transaction_manager =
        concurrency::TransactionManagerFactory::GetInstance();

    bool acquire_owner = GetPlanNode<planner::AbstractScan>().IsForUpdate();
    auto current_txn = executor_context_->GetTransaction();

    // Retrieve next tile group.
    while (current_tile_group_offset_ < table_tile_group_count_) {
      auto tile_group =
          target_table_->GetTileGroup(current_tile_group_offset_++);
      auto tile_group_header = tile_group->GetHeader();

      oid_t active_tuple_count = tile_group->GetNextTupleSlot();

      // Construct position list by looping through tile group
      // and applying the predicate.
      std::vector<oid_t> position_list;
      for (oid_t tuple_id = 0; tuple_id < active_tuple_count; tuple_id++) {
        ItemPointer location(tile_group->GetTileGroupId(), tuple_id);

        auto visibility = transaction_manager.IsVisible(
            current_txn, tile_group_header, tuple_id);

        // check transaction visibility
        if (visibility == VisibilityType::OK) {
          // if the tuple is visible, then perform predicate evaluation.
          if (predicate_ == nullptr) {
            position_list.push_back(tuple_id);
            auto res = transaction_manager.PerformRead(current_txn, location,
                                                       acquire_owner);
            if (!res) {
              transaction_manager.SetTransactionResult(current_txn,
                                                       ResultType::FAILURE);
              return res;
            }
          } else {
            expression::ContainerTuple<storage::TileGroup> tuple(
                tile_group.get(), tuple_id);
            LOG_TRACE("Evaluate predicate for a tuple");
            auto eval =
                predicate_->Evaluate(&tuple, nullptr, executor_context_);
            LOG_TRACE("Evaluation result: %s", eval.GetInfo().c_str());
            if (eval.IsTrue()) {
              position_list.push_back(tuple_id);
              auto res = transaction_manager.PerformRead(current_txn, location,
                                                         acquire_owner);
              if (!res) {
                transaction_manager.SetTransactionResult(current_txn,
                                                         ResultType::FAILURE);
                return res;
              } else {
                LOG_TRACE("Sequential Scan Predicate Satisfied");
              }
            }
          }
        }
      }

      // Don't return empty tiles
      if (position_list.size() == 0) {
        continue;
      }

      // Construct logical tile.
      std::unique_ptr<LogicalTile> logical_tile(LogicalTileFactory::GetTile());
      logical_tile->AddColumns(tile_group, column_ids_);
      logical_tile->AddPositionList(std::move(position_list));

      LOG_TRACE("Information %s", logical_tile->GetInfo().c_str());
      SetOutput(logical_tile.release());
      return true;
    }
  }

  return false;
}
/**
 * @brief Creates logical tile from tile group and applies scan predicate.
 * @return true on success, false otherwise.
 */
@brief Creates logical tile from tile group and applies scan predicate.
@return true on success, false otherwise.
@brief Creates logical tile from tile group and applies scan predicate . @return true on success false otherwise .
bool SeqScanExecutor::DExecute() {
  if (children_.size() == 1 &&
      !(GetRawNode()->GetChildren().size() > 0 &&
        GetRawNode()->GetChildren()[0].get()->GetPlanNodeType() ==
            PlanNodeType::CREATE &&
        ((planner::CreatePlan *)GetRawNode()->GetChildren()[0].get())
                ->GetCreateType() == CreateType::INDEX)) {
    LOG_TRACE("Seq Scan executor :: 1 child ");
    PL_ASSERT(target_table_ == nullptr);
    PL_ASSERT(column_ids_.size() == 0);
    while (children_[0]->Execute()) {
      std::unique_ptr<LogicalTile> tile(children_[0]->GetOutput());
      if (predicate_ != nullptr) {
        for (oid_t tuple_id : *tile) {
          expression::ContainerTuple<LogicalTile> tuple(tile.get(), tuple_id);
          auto eval = predicate_->Evaluate(&tuple, nullptr, executor_context_);
          if (eval.IsFalse()) {
            tile->RemoveVisibility(tuple_id);
          }
        }
      }
      if (0 == tile->GetTupleCount()) {  
        continue;
      }
      SetOutput(tile.release());
      return true;
    }
    return false;
  }
  else if (children_.size() == 0 ||
           (children_.size() == 1 &&
            GetRawNode()->GetChildren().size() > 0 &&
            GetRawNode()->GetChildren()[0].get()->GetPlanNodeType() ==
                PlanNodeType::CREATE &&
            ((planner::CreatePlan *)GetRawNode()->GetChildren()[0].get())
                    ->GetCreateType() == CreateType::INDEX)) {
    LOG_TRACE("Seq Scan executor :: 0 child ");
    PL_ASSERT(target_table_ != nullptr);
    PL_ASSERT(column_ids_.size() > 0);
    if (children_.size() > 0 && !index_done_) {
      children_[0]->Execute();
      index_done_ = true;
    }
    concurrency::TransactionManager &transaction_manager =
        concurrency::TransactionManagerFactory::GetInstance();
    bool acquire_owner = GetPlanNode<planner::AbstractScan>().IsForUpdate();
    auto current_txn = executor_context_->GetTransaction();
    while (current_tile_group_offset_ < table_tile_group_count_) {
      auto tile_group =
          target_table_->GetTileGroup(current_tile_group_offset_++);
      auto tile_group_header = tile_group->GetHeader();
      oid_t active_tuple_count = tile_group->GetNextTupleSlot();
      std::vector<oid_t> position_list;
      for (oid_t tuple_id = 0; tuple_id < active_tuple_count; tuple_id++) {
        ItemPointer location(tile_group->GetTileGroupId(), tuple_id);
        auto visibility = transaction_manager.IsVisible(
            current_txn, tile_group_header, tuple_id);
        if (visibility == VisibilityType::OK) {
          if (predicate_ == nullptr) {
            position_list.push_back(tuple_id);
            auto res = transaction_manager.PerformRead(current_txn, location,
                                                       acquire_owner);
            if (!res) {
              transaction_manager.SetTransactionResult(current_txn,
                                                       ResultType::FAILURE);
              return res;
            }
          } else {
            expression::ContainerTuple<storage::TileGroup> tuple(
                tile_group.get(), tuple_id);
            LOG_TRACE("Evaluate predicate for a tuple");
            auto eval =
                predicate_->Evaluate(&tuple, nullptr, executor_context_);
            LOG_TRACE("Evaluation result: %s", eval.GetInfo().c_str());
            if (eval.IsTrue()) {
              position_list.push_back(tuple_id);
              auto res = transaction_manager.PerformRead(current_txn, location,
                                                         acquire_owner);
              if (!res) {
                transaction_manager.SetTransactionResult(current_txn,
                                                         ResultType::FAILURE);
                return res;
              } else {
                LOG_TRACE("Sequential Scan Predicate Satisfied");
              }
            }
          }
        }
      }
      if (position_list.size() == 0) {
        continue;
      }
      std::unique_ptr<LogicalTile> logical_tile(LogicalTileFactory::GetTile());
      logical_tile->AddColumns(tile_group, column_ids_);
      logical_tile->AddPositionList(std::move(position_list));
      LOG_TRACE("Information %s", logical_tile->GetInfo().c_str());
      SetOutput(logical_tile.release());
      return true;
    }
  }
  return false;
}
bool SeqScanExecutor :: DExecute ( ) { if ( children_ . size ( ) == 1 && ! ( GetRawNode ( ) -> GetChildren ( ) . size ( ) > 0 && GetRawNode ( ) -> GetChildren ( ) [ 0 ] . get ( ) -> GetPlanNodeType ( ) == PlanNodeType :: CREATE && ( ( planner :: CreatePlan * ) GetRawNode ( ) -> GetChildren ( ) [ 0 ] . get ( ) ) -> GetCreateType ( ) == CreateType :: INDEX ) ) { LOG_TRACE ( " " ) ; PL_ASSERT ( target_table_ == nullptr ) ; PL_ASSERT ( column_ids_ . size ( ) == 0 ) ; while ( children_ [ 0 ] -> Execute ( ) ) { std :: unique_ptr < LogicalTile > tile ( children_ [ 0 ] -> GetOutput ( ) ) ; if ( predicate_ != nullptr ) { for ( oid_t tuple_id : * tile ) { expression :: ContainerTuple < LogicalTile > tuple ( tile . get ( ) , tuple_id ) ; auto eval = predicate_ -> Evaluate ( & tuple , nullptr , executor_context_ ) ; if ( eval . IsFalse ( ) ) { tile -> RemoveVisibility ( tuple_id ) ; } } } if ( 0 == tile -> GetTupleCount ( ) ) { continue ; } SetOutput ( tile . release ( ) ) ; return true ; } return false ; } else if ( children_ . size ( ) == 0 || ( children_ . size ( ) == 1 && GetRawNode ( ) -> GetChildren ( ) . size ( ) > 0 && GetRawNode ( ) -> GetChildren ( ) [ 0 ] . get ( ) -> GetPlanNodeType ( ) == PlanNodeType :: CREATE && ( ( planner :: CreatePlan * ) GetRawNode ( ) -> GetChildren ( ) [ 0 ] . get ( ) ) -> GetCreateType ( ) == CreateType :: INDEX ) ) { LOG_TRACE ( " " ) ; PL_ASSERT ( target_table_ != nullptr ) ; PL_ASSERT ( column_ids_ . size ( ) > 0 ) ; if ( children_ . size ( ) > 0 && ! index_done_ ) { children_ [ 0 ] -> Execute ( ) ; index_done_ = true ; } concurrency :: TransactionManager & transaction_manager = concurrency :: TransactionManagerFactory :: GetInstance ( ) ; bool acquire_owner = GetPlanNode < planner :: AbstractScan > ( ) . IsForUpdate ( ) ; auto current_txn = executor_context_ -> GetTransaction ( ) ; while ( current_tile_group_offset_ < table_tile_group_count_ ) { auto tile_group = target_table_ -> GetTileGroup ( current_tile_group_offset_ ++ ) ; auto tile_group_header = tile_group -> GetHeader ( ) ; oid_t active_tuple_count = tile_group -> GetNextTupleSlot ( ) ; std :: vector < oid_t > position_list ; for ( oid_t tuple_id = 0 ; tuple_id < active_tuple_count ; tuple_id ++ ) { ItemPointer location ( tile_group -> GetTileGroupId ( ) , tuple_id ) ; auto visibility = transaction_manager . IsVisible ( current_txn , tile_group_header , tuple_id ) ; if ( visibility == VisibilityType :: OK ) { if ( predicate_ == nullptr ) { position_list . push_back ( tuple_id ) ; auto res = transaction_manager . PerformRead ( current_txn , location , acquire_owner ) ; if ( ! res ) { transaction_manager . SetTransactionResult ( current_txn , ResultType :: FAILURE ) ; return res ; } } else { expression :: ContainerTuple < storage :: TileGroup > tuple ( tile_group . get ( ) , tuple_id ) ; LOG_TRACE ( " " ) ; auto eval = predicate_ -> Evaluate ( & tuple , nullptr , executor_context_ ) ; LOG_TRACE ( " " , eval . GetInfo ( ) . c_str ( ) ) ; if ( eval . IsTrue ( ) ) { position_list . push_back ( tuple_id ) ; auto res = transaction_manager . PerformRead ( current_txn , location , acquire_owner ) ; if ( ! res ) { transaction_manager . SetTransactionResult ( current_txn , ResultType :: FAILURE ) ; return res ; } else { LOG_TRACE ( " " ) ; } } } } } if ( position_list . size ( ) == 0 ) { continue ; } std :: unique_ptr < LogicalTile > logical_tile ( LogicalTileFactory :: GetTile ( ) ) ; logical_tile -> AddColumns ( tile_group , column_ids_ ) ; logical_tile -> AddPositionList ( std :: move ( position_list ) ) ; LOG_TRACE ( " " , logical_tile -> GetInfo ( ) . c_str ( ) ) ; SetOutput ( logical_tile . release ( ) ) ; return true ; } } return false ; }
@brief Creates logical tile from tile group and applies scan predicate.
@brief Creates logical tile from tile group and applies scan predicate .
// Scanning over a logical tile. //There will be a child node on the create index scenario, //but we don't want to use this execution flow // FIXME Check all requirements for children_.size() == 0 case. // Invalidate tuples that don't satisfy the predicate. // if (predicate_->Evaluate(&tuple, nullptr, executor_context_) //        .IsFalse()) { // Avoid returning empty tiles /* Hopefully we needn't do projections here */ // Scanning a table //If we are creating an index, there will be a child //This check is only needed to pass seq_scan_test //unless it is possible to add a executor child //without a corresponding plan. //Check if the plan is what we actually expect. //If it is, confirm it is for indexes //This stops continuous executions due to //a parent and avoids multiple creations //of the same index. // Force to use occ txn manager if dirty read is forbidden // Retrieve next tile group. // Construct position list by looping through tile group // and applying the predicate. // check transaction visibility // if the tuple is visible, then perform predicate evaluation. // Don't return empty tiles // Construct logical tile.