示例#1
0
// Insert a logical tile into a table
TEST_F(MutateTests, InsertTest) {
  auto &txn_manager = concurrency::OptimisticTxnManager::GetInstance();
  // We are going to insert a tile group into a table in this test
  std::unique_ptr<storage::DataTable> source_data_table(
      ExecutorTestsUtil::CreateAndPopulateTable());
  std::unique_ptr<storage::DataTable> dest_data_table(
      ExecutorTestsUtil::CreateTable());
  const std::vector<storage::Tuple *> tuples;

  EXPECT_EQ(source_data_table->GetTileGroupCount(), 3);
  EXPECT_EQ(dest_data_table->GetTileGroupCount(), 1);

  auto txn = txn_manager.BeginTransaction();
  std::unique_ptr<executor::ExecutorContext> context(
      new executor::ExecutorContext(txn));

  planner::InsertPlan node(dest_data_table.get(), nullptr);
  executor::InsertExecutor executor(&node, context.get());

  MockExecutor child_executor;
  executor.AddChild(&child_executor);

  // Uneventful init...
  EXPECT_CALL(child_executor, DInit()).WillOnce(Return(true));

  // Will return one tile.
  EXPECT_CALL(child_executor, DExecute())
      .WillOnce(Return(true))
      .WillOnce(Return(false));

  // Construct input logical tile
  auto physical_tile_group = source_data_table->GetTileGroup(0);
  auto tile_count = physical_tile_group->GetTileCount();
  std::vector<std::shared_ptr<storage::Tile> > physical_tile_refs;
  for (oid_t tile_itr = 0; tile_itr < tile_count; tile_itr++)
    physical_tile_refs.push_back(
        physical_tile_group->GetTileReference(tile_itr));

  std::unique_ptr<executor::LogicalTile> source_logical_tile(
      executor::LogicalTileFactory::WrapTiles(physical_tile_refs));

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

  EXPECT_TRUE(executor.Init());

  EXPECT_TRUE(executor.Execute());
  EXPECT_FALSE(executor.Execute());

  txn_manager.CommitTransaction();

  // We have inserted all the tuples in this logical tile
  EXPECT_EQ(dest_data_table->GetTileGroupCount(), 1);
}
// "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);
  }
}
// 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));
  }
}