src/backend/bridge/dml/executor/plan_executor.cpp
/**
 * @brief Build a executor tree and execute it.
 * Use std::vector<Value> as params to make it more elegant for networking
 * Before ExecutePlan, a node first receives value list, so we should pass
 * value list directly rather than passing Postgres's ParamListInfo
 * @return status of execution.
 */
@brief Build a executor tree and execute it.
Use std::vector as params to make it more elegant for networking
Before ExecutePlan, a node first receives value list, so we should pass
value list directly rather than passing Postgres's ParamListInfo
@return status of execution.
@brief Build a executor tree and execute it . Use std :: vector as params to make it more elegant for networking Before ExecutePlan a node first receives value list so we should pass value list directly rather than passing Postgres ' s ParamListInfo @return status of execution .
peloton_status PlanExecutor::ExecutePlan(const planner::AbstractPlan *plan,
                                         const std::vector<Value> &params,
                                         TupleDesc tuple_desc) {
  peloton_status p_status;
  if (plan == nullptr) return p_status;
  LOG_TRACE("PlanExecutor Start ");
  bool status;
  bool init_failure = false;
  bool single_statement_txn = false;
  List *slots = NULL;
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = peloton::concurrency::current_txn;
  if (txn == nullptr) {
    single_statement_txn = true;
    txn = txn_manager.BeginTransaction();
  }
  assert(txn);
  LOG_TRACE("Txn ID = %lu ", txn->GetTransactionId());
  LOG_TRACE("Building the executor tree");
  std::unique_ptr<executor::ExecutorContext> executor_context(
  BuildExecutorContext(params, txn));
  std::unique_ptr<executor::AbstractExecutor> executor_tree(
      BuildExecutorTree(nullptr, plan, executor_context.get()));
  LOG_TRACE("Initializing the executor tree");
  status = executor_tree->Init();
  if (status == false) {
    init_failure = true;
    txn->SetResult(Result::RESULT_FAILURE);
    goto cleanup;
  }
  LOG_TRACE("Running the executor tree");
  for (;;) {
    status = executor_tree->Execute();
    if (status == false) {
      break;
    }
    std::unique_ptr<executor::LogicalTile> logical_tile(
        executor_tree->GetOutput());
    if (logical_tile.get() == nullptr) {
      continue;
    }
    for (oid_t tuple_id : *logical_tile) {
      expression::ContainerTuple<executor::LogicalTile> cur_tuple(
          logical_tile.get(), tuple_id);
      auto slot = TupleTransformer::GetPostgresTuple(&cur_tuple, tuple_desc);
      if (slot != nullptr) {
        slots = lappend(slots, slot);
      }
    }
  }
  p_status.m_processed = executor_context->num_processed;
  p_status.m_result_slots = slots;
cleanup:
  LOG_TRACE("About to commit: single stmt: %d, init_failure: %d, status: %d",
            single_statement_txn, init_failure, txn->GetResult());
  if (single_statement_txn == true || init_failure == true) {
    auto status = txn->GetResult();
    switch (status) {
      case Result::RESULT_SUCCESS:
        p_status.m_result = txn_manager.CommitTransaction();
        break;
      case Result::RESULT_FAILURE:
      default:
        p_status.m_result = txn_manager.AbortTransaction();
    }
  }
  CleanExecutorTree(executor_tree.get());
  return p_status;
}
peloton_status PlanExecutor :: ExecutePlan ( const planner :: AbstractPlan * plan , const std :: vector < Value > & params , TupleDesc tuple_desc ) { peloton_status p_status ; if ( plan == nullptr ) return p_status ; LOG_TRACE ( " " ) ; bool status ; bool init_failure = false ; bool single_statement_txn = false ; List * slots = NULL ; auto & txn_manager = concurrency :: TransactionManagerFactory :: GetInstance ( ) ; auto txn = peloton :: concurrency :: current_txn ; if ( txn == nullptr ) { single_statement_txn = true ; txn = txn_manager . BeginTransaction ( ) ; } assert ( txn ) ; LOG_TRACE ( " " , txn -> GetTransactionId ( ) ) ; LOG_TRACE ( " " ) ; std :: unique_ptr < executor :: ExecutorContext > executor_context ( BuildExecutorContext ( params , txn ) ) ; std :: unique_ptr < executor :: AbstractExecutor > executor_tree ( BuildExecutorTree ( nullptr , plan , executor_context . get ( ) ) ) ; LOG_TRACE ( " " ) ; status = executor_tree -> Init ( ) ; if ( status == false ) { init_failure = true ; txn -> SetResult ( Result :: RESULT_FAILURE ) ; goto cleanup ; } LOG_TRACE ( " " ) ; for ( ; ; ) { status = executor_tree -> Execute ( ) ; if ( status == false ) { break ; } std :: unique_ptr < executor :: LogicalTile > logical_tile ( executor_tree -> GetOutput ( ) ) ; if ( logical_tile . get ( ) == nullptr ) { continue ; } for ( oid_t tuple_id : * logical_tile ) { expression :: ContainerTuple < executor :: LogicalTile > cur_tuple ( logical_tile . get ( ) , tuple_id ) ; auto slot = TupleTransformer :: GetPostgresTuple ( & cur_tuple , tuple_desc ) ; if ( slot != nullptr ) { slots = lappend ( slots , slot ) ; } } } p_status . m_processed = executor_context -> num_processed ; p_status . m_result_slots = slots ; cleanup : LOG_TRACE ( " " , single_statement_txn , init_failure , txn -> GetResult ( ) ) ; if ( single_statement_txn == true || init_failure == true ) { auto status = txn -> GetResult ( ) ; switch ( status ) { case Result :: RESULT_SUCCESS : p_status . m_result = txn_manager . CommitTransaction ( ) ; break ; case Result :: RESULT_FAILURE : default : p_status . m_result = txn_manager . AbortTransaction ( ) ; } } CleanExecutorTree ( executor_tree . get ( ) ) ; return p_status ; }
@brief Build a executor tree and execute it.
@brief Build a executor tree and execute it .
// This happens for single statement queries in PG // Use const std::vector<Value> &params to make it more elegant for network //auto executor_context = BuildExecutorContext(param_list, txn); // Build the executor tree // Initialize the executor tree // Abort and cleanup // Execute the tree until we get result tiles from root node // Stop // Some executors don't return logical tiles (e.g., Update). // Go over the logical tile // Set the result // final cleanup // should we commit or abort ? // Commit // Abort // clean up executor tree