// 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)); } }