src/backend/bridge/dml/executor/plan_executor.cpp
int PlanExecutor::ExecutePlan(const planner::AbstractPlan *plan,
    const std::vector<Value> &params,
    std::vector<std::unique_ptr<executor::LogicalTile>>& logical_tile_list) {

  if (plan == nullptr) return -1;

  LOG_TRACE("PlanExecutor Start ");

  bool status;
  bool init_failure = false;
  bool single_statement_txn = false;

  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = peloton::concurrency::current_txn;

  // This happens for single statement queries in PG
  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");

  // Use const std::vector<Value> &params to make it more elegant for network
  std::unique_ptr<executor::ExecutorContext> executor_context(
  BuildExecutorContext(params, txn));

  // Build the executor tree
  std::unique_ptr<executor::AbstractExecutor> executor_tree(
      BuildExecutorTree(nullptr, plan, executor_context.get()));

  LOG_TRACE("Initializing the executor tree");

  // Initialize the executor tree
  status = executor_tree->Init();

  // Abort and cleanup
  if (status == false) {
    init_failure = true;
    txn->SetResult(Result::RESULT_FAILURE);
    goto cleanup;
  }

  LOG_TRACE("Running the executor tree");

  // Execute the tree until we get result tiles from root node
  for (;;) {
    status = executor_tree->Execute();

    // Stop
    if (status == false) {
      break;
    }

    std::unique_ptr<executor::LogicalTile> logical_tile(
        executor_tree->GetOutput());

    // Some executors don't return logical tiles (e.g., Update).
    if (logical_tile.get() == nullptr) {
      continue;
    }

    logical_tile_list.push_back(std::move(logical_tile));
  }

// final cleanup
cleanup:

  LOG_TRACE("About to commit: single stmt: %d, init_failure: %d, status: %d",
            single_statement_txn, init_failure, txn->GetResult());

  // clean up executor tree
  CleanExecutorTree(executor_tree.get());

  // should we commit or abort ?
  if (single_statement_txn == true || init_failure == true) {
    auto status = txn->GetResult();
    switch (status) {
      case Result::RESULT_SUCCESS:
        // Commit
        return
            executor_context->num_processed;

        break;

      case Result::RESULT_FAILURE:
      default:
        // Abort
       return -1;
    }
  }
  return executor_context->num_processed;
}
/**
 * @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 number of executed tuples and logical_tile_list
 */
@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 number of executed tuples and logical_tile_list
@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 number of executed tuples and logical_tile_list
int PlanExecutor::ExecutePlan(const planner::AbstractPlan *plan,
    const std::vector<Value> &params,
    std::vector<std::unique_ptr<executor::LogicalTile>>& logical_tile_list) {
  if (plan == nullptr) return -1;
  LOG_TRACE("PlanExecutor Start ");
  bool status;
  bool init_failure = false;
  bool single_statement_txn = false;
  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;
    }
    logical_tile_list.push_back(std::move(logical_tile));
  }
cleanup:
  LOG_TRACE("About to commit: single stmt: %d, init_failure: %d, status: %d",
            single_statement_txn, init_failure, txn->GetResult());
  CleanExecutorTree(executor_tree.get());
  if (single_statement_txn == true || init_failure == true) {
    auto status = txn->GetResult();
    switch (status) {
      case Result::RESULT_SUCCESS:
        return
            executor_context->num_processed;
        break;
      case Result::RESULT_FAILURE:
      default:
       return -1;
    }
  }
  return executor_context->num_processed;
}
int PlanExecutor :: ExecutePlan ( const planner :: AbstractPlan * plan , const std :: vector < Value > & params , std :: vector < std :: unique_ptr < executor :: LogicalTile > > & logical_tile_list ) { if ( plan == nullptr ) return -1 ; LOG_TRACE ( " " ) ; bool status ; bool init_failure = false ; bool single_statement_txn = false ; 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 ; } logical_tile_list . push_back ( std :: move ( logical_tile ) ) ; } cleanup : LOG_TRACE ( " " , single_statement_txn , init_failure , txn -> GetResult ( ) ) ; CleanExecutorTree ( executor_tree . get ( ) ) ; if ( single_statement_txn == true || init_failure == true ) { auto status = txn -> GetResult ( ) ; switch ( status ) { case Result :: RESULT_SUCCESS : return executor_context -> num_processed ; break ; case Result :: RESULT_FAILURE : default : return -1 ; } } return executor_context -> num_processed ; }
@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 // 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). // final cleanup // clean up executor tree // should we commit or abort ? // Commit // Abort