Ejemplo n.º 1
0
TEST_F(MutateTests, DeleteTest) {
  // We are going to insert a tile group into a table in this test

  storage::DataTable *table = ExecutorTestsUtil::CreateTable();
  auto testing_pool = TestingHarness::GetInstance().GetTestingPool();

  LaunchParallelTest(1, InsertTuple, table, testing_pool);
  LaunchParallelTest(1, DeleteTuple, table);

  auto &txn_manager = concurrency::OptimisticTxnManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));
  // Seq scan
  std::vector<oid_t> column_ids = {0};
  planner::SeqScanPlan seq_scan_node(table, nullptr, column_ids);
  executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, context.get());
  EXPECT_TRUE(seq_scan_executor.Init());

  auto tuple_cnt = 0;
  while (seq_scan_executor.Execute()) {
    std::unique_ptr<executor::LogicalTile> result_logical_tile(
        seq_scan_executor.GetOutput());
    tuple_cnt += result_logical_tile->GetTupleCount();
  }
  txn_manager.CommitTransaction();
  EXPECT_EQ(tuple_cnt, 6);
  delete table;
  tuple_id = 0;
}
Ejemplo n.º 2
0
/**
 * @brief Convenience function to pass a single logical tile through an
 *        executor which has only one child.
 * @param executor Executor to pass logical tile through.
 * @param source_logical_tile Logical tile to pass through executor.
 * @param check the value of logical tiles
 *
 * @return Pointer to processed logical tile.
 */
executor::LogicalTile *ExecutorTestsUtil::ExecuteTile(
    executor::AbstractExecutor *executor,
    executor::LogicalTile *source_logical_tile) {
  MockExecutor child_executor;
  executor->AddChild(&child_executor);

  // Uneventful init...
  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));
  EXPECT_TRUE(executor->Init());

  // Where the main work takes place...
  EXPECT_CALL(child_executor, DExecute())
      .WillOnce(Return(true))
      .WillOnce(Return(false));

  EXPECT_CALL(child_executor, GetOutput())
      .WillOnce(Return(source_logical_tile));

  EXPECT_TRUE(executor->Execute());
  std::unique_ptr<executor::LogicalTile> result_logical_tile(
      executor->GetOutput());
  EXPECT_THAT(result_logical_tile, NotNull());
  EXPECT_THAT(executor->Execute(), false);

  return result_logical_tile.release();
}
// "Pass-through" test case. There is nothing to materialize as
// there is only one base tile in the logical tile.
TEST_F(MaterializationTests, SingleBaseTileTest) {
  const int tuple_count = 9;
  std::shared_ptr<storage::TileGroup> tile_group(
      ExecutorTestsUtil::CreateTileGroup(tuple_count));

  ExecutorTestsUtil::PopulateTiles(tile_group, tuple_count);

  // Create logical tile from single base tile.
  auto source_base_tile = tile_group->GetTileReference(0);

  // Add a reference because we are going to wrap around it and we don't own it
  std::unique_ptr<executor::LogicalTile> source_logical_tile(
      executor::LogicalTileFactory::WrapTiles({source_base_tile}));

  // Pass through materialization executor.
  executor::MaterializationExecutor executor(nullptr, nullptr);
  std::unique_ptr<executor::LogicalTile> result_logical_tile(
      ExecutorTestsUtil::ExecuteTile(&executor, source_logical_tile.release()));

  // Verify that logical tile is only made up of a single base tile.
  int num_cols = result_logical_tile->GetColumnCount();
  EXPECT_EQ(2, num_cols);
  storage::Tile *result_base_tile = result_logical_tile->GetBaseTile(0);
  EXPECT_THAT(result_base_tile, NotNull());
  EXPECT_TRUE(source_base_tile.get() == result_base_tile);
  EXPECT_EQ(result_logical_tile->GetBaseTile(1), result_base_tile);

  // Check that the base tile has the correct values.
  for (int i = 0; i < tuple_count; i++) {
    type::Value val0 = (result_base_tile->GetValue(i, 0));
    type::Value val1 = (result_base_tile->GetValue(i, 1));
    type::CmpBool cmp = (val0.CompareEquals(
      type::ValueFactory::GetIntegerValue(ExecutorTestsUtil::PopulatedValue(i, 0))));
    EXPECT_TRUE(cmp == type::CMP_TRUE);
    cmp = val1.CompareEquals(type::ValueFactory::GetIntegerValue(
        ExecutorTestsUtil::PopulatedValue(i, 1)));
    EXPECT_TRUE(cmp == type::CMP_TRUE);

    // Double check that logical tile is functioning.
    type::Value logic_val0 = (result_logical_tile->GetValue(i, 0));
    type::Value logic_val1 = (result_logical_tile->GetValue(i, 1));
    cmp = (logic_val0.CompareEquals(val0));
    EXPECT_TRUE(cmp == type::CMP_TRUE);
    cmp = (logic_val1.CompareEquals(val1));
    EXPECT_TRUE(cmp == type::CMP_TRUE);
  }
}
TEST_F(GCDeleteTestVacuum, DeleteTest) {

  peloton::gc::GCManagerFactory::Configure(type);
  peloton::gc::GCManagerFactory::GetInstance().StartGC();

  auto *table = ExecutorTestsUtil::CreateTable(1024);
  auto &manager = catalog::Manager::GetInstance();
  storage::Database db(DEFAULT_DB_ID);
  manager.AddDatabase(&db);
  db.AddTable(table);
  // We are going to insert a tile group into a table in this test

  auto testing_pool = TestingHarness::GetInstance().GetTestingPool();

  auto before_insert = catalog::Manager::GetInstance().GetMemoryFootprint();
  LaunchParallelTest(1, InsertTuple, table, testing_pool);
  auto after_insert = catalog::Manager::GetInstance().GetMemoryFootprint();
  EXPECT_GT(after_insert, before_insert);
  LaunchParallelTest(1, DeleteTuple, table);
  std::this_thread::sleep_for(std::chrono::seconds(10));
  auto after_delete = catalog::Manager::GetInstance().GetMemoryFootprint();
  EXPECT_EQ(after_insert, after_delete);
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));
  // Seq scan
  std::vector<oid_t> column_ids = {0};
  planner::SeqScanPlan seq_scan_node(table, nullptr, column_ids);
  executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, context.get());
  EXPECT_TRUE(seq_scan_executor.Init());

  auto tuple_cnt = 0;
  while (seq_scan_executor.Execute()) {
    std::unique_ptr<executor::LogicalTile> result_logical_tile(
        seq_scan_executor.GetOutput());
    tuple_cnt += result_logical_tile->GetTupleCount();
  }
  txn_manager.CommitTransaction();
  EXPECT_EQ(tuple_cnt, 6);

  tuple_id = 0;
}
Ejemplo n.º 5
0
int SeqScanCount(storage::DataTable *table,
                 const std::vector<oid_t> &column_ids,
                 expression::AbstractExpression *predicate) {
  auto &txn_manager = concurrency::OptimisticTxnManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  planner::SeqScanPlan seq_scan_node(table, predicate, column_ids);
  executor::SeqScanExecutor seq_scan_executor(&seq_scan_node, context.get());

  EXPECT_TRUE(seq_scan_executor.Init());
  auto tuple_cnt = 0;

  while (seq_scan_executor.Execute()) {
    std::unique_ptr<executor::LogicalTile> result_logical_tile(
        seq_scan_executor.GetOutput());
    tuple_cnt += result_logical_tile->GetTupleCount();
  }

  txn_manager.CommitTransaction();

  return tuple_cnt;
}
Ejemplo n.º 6
0
void ExecuteJoinTest(PlanNodeType join_algorithm, PelotonJoinType join_type, oid_t join_test_type) {
  //===--------------------------------------------------------------------===//
  // Mock table scan executors
  //===--------------------------------------------------------------------===//

  MockExecutor left_table_scan_executor, right_table_scan_executor;

  // Create a table and wrap it in logical tile
  size_t tile_group_size = TESTS_TUPLES_PER_TILEGROUP;
  size_t left_table_tile_group_count = 3;
  size_t right_table_tile_group_count = 2;

  auto &txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  auto txn_id = txn->GetTransactionId();

  // Left table has 3 tile groups
  std::unique_ptr<storage::DataTable> left_table(
      ExecutorTestsUtil::CreateTable(tile_group_size));
  ExecutorTestsUtil::PopulateTable(
      txn, left_table.get(),
      tile_group_size * left_table_tile_group_count, false,
      false, false);

  // Right table has 2 tile groups
  std::unique_ptr<storage::DataTable> right_table(
      ExecutorTestsUtil::CreateTable(tile_group_size));
  ExecutorTestsUtil::PopulateTable(
      txn, right_table.get(),
      tile_group_size * right_table_tile_group_count, false,
      false, false);

  txn_manager.CommitTransaction();

  //std::cout << (*left_table);

  //std::cout << (*right_table);

  // Wrap the input tables with logical tiles
  std::unique_ptr<executor::LogicalTile> left_table_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(left_table->GetTileGroup(0),
                                                  txn_id));
  std::unique_ptr<executor::LogicalTile> left_table_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(left_table->GetTileGroup(1),
                                                  txn_id));
  std::unique_ptr<executor::LogicalTile> left_table_logical_tile3(
      executor::LogicalTileFactory::WrapTileGroup(left_table->GetTileGroup(2),
                                                  txn_id));

  std::unique_ptr<executor::LogicalTile> right_table_logical_tile1(
      executor::LogicalTileFactory::WrapTileGroup(
          right_table->GetTileGroup(0),
          txn_id));

  std::unique_ptr<executor::LogicalTile> right_table_logical_tile2(
      executor::LogicalTileFactory::WrapTileGroup(
          right_table->GetTileGroup(1),
          txn_id));

  // Left scan executor returns logical tiles from the left table

  EXPECT_CALL(left_table_scan_executor, DInit()).WillOnce(Return(true));

  //===--------------------------------------------------------------------===//
  // Setup left table
  //===--------------------------------------------------------------------===//

  if(join_test_type == BASIC_TEST) {

    EXPECT_CALL(left_table_scan_executor, DExecute())
        .WillOnce(Return(true))
        .WillOnce(Return(true))
        .WillOnce(Return(true))
        .WillOnce(Return(false));

    EXPECT_CALL(left_table_scan_executor, GetOutput())
        .WillOnce(Return(left_table_logical_tile1.release()))
        .WillOnce(Return(left_table_logical_tile2.release()))
        .WillOnce(Return(left_table_logical_tile3.release()));

  }

  // Right scan executor returns logical tiles from the right table

  EXPECT_CALL(right_table_scan_executor, DInit()).WillOnce(Return(true));

  //===--------------------------------------------------------------------===//
  // Setup right table
  //===--------------------------------------------------------------------===//

  if(join_test_type == BASIC_TEST) {

    EXPECT_CALL(right_table_scan_executor, DExecute())
         .WillOnce(Return(true))
         .WillOnce(Return(true))
         .WillOnce(Return(false));

     EXPECT_CALL(right_table_scan_executor, GetOutput())
         .WillOnce(Return(right_table_logical_tile1.release()))
         .WillOnce(Return(right_table_logical_tile2.release()));

  }

  //===--------------------------------------------------------------------===//
  // Setup join plan nodes and executors and run them
  //===--------------------------------------------------------------------===//

  oid_t result_tuple_count = 0;
  oid_t tuples_with_null = 0;
  auto projection = JoinTestsUtil::CreateProjection();

  // Construct predicate
  expression::AbstractExpression *predicate =
      JoinTestsUtil::CreateJoinPredicate();

  // Differ based on join algorithm
  switch (join_algorithm) {
    case PLAN_NODE_TYPE_NESTLOOP: {
      // Create nested loop join plan node.
      planner::NestedLoopJoinPlan nested_loop_join_node(join_type, predicate,
                                                        projection);

      // Run the nested loop join executor
      executor::NestedLoopJoinExecutor nested_loop_join_executor(
          &nested_loop_join_node, nullptr);

      // Construct the executor tree
      nested_loop_join_executor.AddChild(&left_table_scan_executor);
      nested_loop_join_executor.AddChild(&right_table_scan_executor);

      // Run the nested loop join executor
      EXPECT_TRUE(nested_loop_join_executor.Init());
      while (nested_loop_join_executor.Execute() == true) {
        std::unique_ptr<executor::LogicalTile> result_logical_tile(
            nested_loop_join_executor.GetOutput());

        if (result_logical_tile != nullptr) {
          result_tuple_count += result_logical_tile->GetTupleCount();
          tuples_with_null +=
              CountTuplesWithNullFields(result_logical_tile.get());
          //std::cout << (*result_logical_tile);
        }
      }

    } break;

    case PLAN_NODE_TYPE_MERGEJOIN: {
      // Create join clauses
      std::vector<planner::MergeJoinPlan::JoinClause> join_clauses;
      join_clauses = CreateJoinClauses();

      // Create merge join plan node
      planner::MergeJoinPlan merge_join_node(join_type, predicate, projection,
                                             join_clauses);

      // Construct the merge join executor
      executor::MergeJoinExecutor merge_join_executor(&merge_join_node,
                                                      nullptr);

      // Construct the executor tree
      merge_join_executor.AddChild(&left_table_scan_executor);
      merge_join_executor.AddChild(&right_table_scan_executor);

      // Run the merge join executor
      EXPECT_TRUE(merge_join_executor.Init());
      while (merge_join_executor.Execute() == true) {
        std::unique_ptr<executor::LogicalTile> result_logical_tile(
            merge_join_executor.GetOutput());

        if (result_logical_tile != nullptr) {
          result_tuple_count += result_logical_tile->GetTupleCount();
          tuples_with_null +=
              CountTuplesWithNullFields(result_logical_tile.get());
          //std::cout << (*result_logical_tile);
        }
      }

    } break;

    case PLAN_NODE_TYPE_HASHJOIN: {
      // Create hash plan node
      expression::AbstractExpression *right_table_attr_1 =
          new expression::TupleValueExpression(1, 1);

      std::vector<std::unique_ptr<const expression::AbstractExpression> >
          hash_keys;
      hash_keys.emplace_back(right_table_attr_1);

      // Create hash plan node
      planner::HashPlan hash_plan_node(hash_keys);

      // Construct the hash executor
      executor::HashExecutor hash_executor(&hash_plan_node, nullptr);

      // Create hash join plan node.
      planner::HashJoinPlan hash_join_plan_node(join_type, predicate,
                                                projection);

      // Construct the hash join executor
      executor::HashJoinExecutor hash_join_executor(&hash_join_plan_node,
                                                    nullptr);

      // Construct the executor tree
      hash_join_executor.AddChild(&left_table_scan_executor);
      hash_join_executor.AddChild(&hash_executor);

      hash_executor.AddChild(&right_table_scan_executor);

      // Run the hash_join_executor
      EXPECT_TRUE(hash_join_executor.Init());
      while (hash_join_executor.Execute() == true) {
        std::unique_ptr<executor::LogicalTile> result_logical_tile(
            hash_join_executor.GetOutput());

        if (result_logical_tile != nullptr) {
          result_tuple_count += result_logical_tile->GetTupleCount();
          tuples_with_null +=
              CountTuplesWithNullFields(result_logical_tile.get());
          // std::cout << (*result_logical_tile);
        }
      }

    } break;

    default:
      throw Exception("Unsupported join algorithm : " +
                      std::to_string(join_algorithm));
      break;
  }

  //===--------------------------------------------------------------------===//
  // Execute test
  //===--------------------------------------------------------------------===//

  if(join_test_type == BASIC_TEST) {

    // Check output
    switch (join_type) {
      case JOIN_TYPE_INNER:
        EXPECT_EQ(result_tuple_count, 10);
        EXPECT_EQ(tuples_with_null, 0);
        break;

      case JOIN_TYPE_LEFT:
        EXPECT_EQ(result_tuple_count, 15);
        EXPECT_EQ(tuples_with_null, 5);
        break;

      case JOIN_TYPE_RIGHT:
        EXPECT_EQ(result_tuple_count, 10);
        EXPECT_EQ(tuples_with_null, 0);
        break;

      case JOIN_TYPE_OUTER:
        EXPECT_EQ(result_tuple_count, 15);
        EXPECT_EQ(tuples_with_null, 5);
        break;

      default:
        throw Exception("Unsupported join type : " + std::to_string(join_type));
        break;
    }

  }

}
Ejemplo n.º 7
0
// Materializing logical tile composed of two base tiles.
// The materialized tile's output columns are reordered.
// Also, one of the columns is dropped.
TEST_F(MaterializationTests, TwoBaseTilesWithReorderTest) {
  const int tuple_count = 9;
  std::shared_ptr<storage::TileGroup> tile_group(
      ExecutorTestsUtil::CreateTileGroup(tuple_count));

  ExecutorTestsUtil::PopulateTiles(tile_group, tuple_count);

  // Create logical tile from two base tiles.
  const std::vector<std::shared_ptr<storage::Tile> > source_base_tiles = {
      tile_group->GetTileReference(0), tile_group->GetTileReference(1)};

  // Add a reference because we are going to wrap around it and we don't own it
  std::unique_ptr<executor::LogicalTile> source_logical_tile(
      executor::LogicalTileFactory::WrapTiles(source_base_tiles));

  // Create materialization node for this test.
  // Construct output schema. We drop column 3 and reorder the others to 3,1,0.
  std::vector<catalog::Column> output_columns;
  // Note that Column 3 in the tile group is column 1 in the second tile.
  output_columns.push_back(source_base_tiles[1]->GetSchema()->GetColumn(1));
  output_columns.push_back(source_base_tiles[0]->GetSchema()->GetColumn(1));
  output_columns.push_back(source_base_tiles[0]->GetSchema()->GetColumn(0));
  std::unique_ptr<catalog::Schema> output_schema(
      new catalog::Schema(output_columns));

  // Construct mapping using the ordering mentioned above.
  std::unordered_map<oid_t, oid_t> old_to_new_cols;
  old_to_new_cols[3] = 0;
  old_to_new_cols[1] = 1;
  old_to_new_cols[0] = 2;
  bool physify_flag = true;  // is going to create a physical tile
  planner::MaterializationPlan node(old_to_new_cols, output_schema.release(),
                                    physify_flag);

  // Pass through materialization executor.
  executor::MaterializationExecutor executor(&node, nullptr);
  std::unique_ptr<executor::LogicalTile> result_logical_tile(
      ExecutorTestsUtil::ExecuteTile(&executor, source_logical_tile.release()));

  // Verify that logical tile is only made up of a single base tile.
  int num_cols = result_logical_tile->GetColumnCount();
  EXPECT_EQ(3, num_cols);
  storage::Tile *result_base_tile = result_logical_tile->GetBaseTile(0);
  EXPECT_THAT(result_base_tile, NotNull());
  EXPECT_EQ(result_base_tile, result_logical_tile->GetBaseTile(1));
  EXPECT_EQ(result_base_tile, result_logical_tile->GetBaseTile(2));

  // Check that the base tile has the correct values.
  for (int i = 0; i < tuple_count; i++) {
    // Output column 2.
    EXPECT_EQ(
        ValueFactory::GetIntegerValue(ExecutorTestsUtil::PopulatedValue(i, 0)),
        result_base_tile->GetValue(i, 2));
    // Output column 1.
    EXPECT_EQ(
        ValueFactory::GetIntegerValue(ExecutorTestsUtil::PopulatedValue(i, 1)),
        result_base_tile->GetValue(i, 1));
    // Output column 0.
    Value string_value(ValueFactory::GetStringValue(
        std::to_string(ExecutorTestsUtil::PopulatedValue(i, 3))));
    EXPECT_EQ(string_value, result_base_tile->GetValue(i, 0));

    // Double check that logical tile is functioning.
    EXPECT_EQ(result_base_tile->GetValue(i, 0),
              result_logical_tile->GetValue(i, 0));
    EXPECT_EQ(result_base_tile->GetValue(i, 1),
              result_logical_tile->GetValue(i, 1));
    EXPECT_EQ(result_base_tile->GetValue(i, 2),
              result_logical_tile->GetValue(i, 2));
  }
}