@@ -53,13 +53,15 @@ class TableScanTranslatorTest : public PelotonCodeGenTest {
5353
5454 for (oid_t col_itr = 0 ; col_itr <= col_count; col_itr++) {
5555 auto column =
56- catalog::Column (type::TypeId::INTEGER, type::Type::GetTypeSize (type::TypeId::INTEGER),
56+ catalog::Column (type::TypeId::INTEGER,
57+ type::Type::GetTypeSize (type::TypeId::INTEGER),
5758 " FIELD" + std::to_string (col_itr), is_inlined);
5859
5960 columns.push_back (column);
6061 }
6162
62- std::unique_ptr<catalog::Schema> table_schema = std::unique_ptr<catalog::Schema>(new catalog::Schema (columns));
63+ std::unique_ptr<catalog::Schema> table_schema =
64+ std::unique_ptr<catalog::Schema>(new catalog::Schema (columns));
6365 std::string table_name (" TEST_TABLE" );
6466
6567 // ///////////////////////////////////////////////////////
@@ -716,5 +718,181 @@ TEST_F(TableScanTranslatorTest, ScanColumnLayout) {
716718 ExecuteTileGroupTest (LayoutType::COLUMN);
717719}
718720
721+ TEST_F (TableScanTranslatorTest, MultiLayoutScan) {
722+ //
723+ // Creates a table with LayoutType::ROW
724+ // Sets the default_layout_ as LayoutType::COLUMN
725+ // Inserts tuples
726+ // Sets the default_layout_ as LayoutType::HYBRID
727+ // Inserts some more tuples
728+ // invokes the TableScanTranslator
729+ //
730+
731+ const int tuples_per_tilegroup= 100 ;
732+ const int col_count = 6 ;
733+ const bool is_inlined = true ;
734+ oid_t tuple_count = 100 ;
735+
736+
737+ // ///////////////////////////////////////////////////////
738+ // Define the schema.
739+ // ///////////////////////////////////////////////////////
740+
741+ std::vector<catalog::Column> columns;
742+
743+ for (oid_t col_itr = 0 ; col_itr < col_count; col_itr++) {
744+ auto column =
745+ catalog::Column (type::TypeId::INTEGER,
746+ type::Type::GetTypeSize (type::TypeId::INTEGER),
747+ " FIELD" + std::to_string (col_itr), is_inlined);
748+
749+ columns.push_back (column);
750+ }
751+
752+ std::unique_ptr<catalog::Schema> table_schema =
753+ std::unique_ptr<catalog::Schema>(new catalog::Schema (columns));
754+ std::string table_name (" MULTI_LAYOUT_TABLE" );
755+
756+ // ///////////////////////////////////////////////////////
757+ // Create table.
758+ // ///////////////////////////////////////////////////////
759+
760+ bool is_catalog = false ;
761+ auto *catalog = catalog::Catalog::GetInstance ();
762+ auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance ();
763+ const bool allocate = true ;
764+ auto txn = txn_manager.BeginTransaction ();
765+
766+ // Insert table in catalog
767+ catalog->CreateTable (test_db_name, table_name, std::move (table_schema),
768+ txn, is_catalog, tuples_per_tilegroup, LayoutType::ROW);
769+ txn_manager.EndTransaction (txn);
770+
771+ auto table = GetDatabase ().GetTableWithName (table_name);
772+
773+ // ///////////////////////////////////////////////////////
774+ // Reset default_layout_ to LayoutType::COLUMN
775+ // ///////////////////////////////////////////////////////
776+ table->ResetDefaultLayout (LayoutType::COLUMN);
777+
778+ // ///////////////////////////////////////////////////////
779+ // Load in 100 tuples
780+ // ///////////////////////////////////////////////////////
781+ txn = txn_manager.BeginTransaction ();
782+ auto table_schema_ptr = table->GetSchema ();
783+ auto testing_pool = TestingHarness::GetInstance ().GetTestingPool ();
784+
785+ for (oid_t row_id = 0 ; row_id < tuple_count; row_id++) {
786+ int populate_value = row_id;
787+
788+ storage::Tuple tuple (table_schema_ptr, allocate);
789+
790+ for (oid_t col_id = 0 ; col_id < col_count; col_id++) {
791+ auto value = type::ValueFactory::GetIntegerValue (populate_value + col_id);
792+ tuple.SetValue (col_id, value, testing_pool);
793+ }
794+
795+ ItemPointer *index_entry_ptr = nullptr ;
796+ ItemPointer tuple_slot_id =
797+ table->InsertTuple (&tuple, txn, &index_entry_ptr);
798+
799+ EXPECT_TRUE (tuple_slot_id.block != INVALID_OID);
800+ EXPECT_TRUE (tuple_slot_id.offset != INVALID_OID);
801+
802+ txn_manager.PerformInsert (txn, tuple_slot_id, index_entry_ptr);
803+ }
804+
805+ txn_manager.CommitTransaction (txn);
806+
807+ // ///////////////////////////////////////////////////////
808+ // Set default_layout_ to LayoutType::HYBRID
809+ // ///////////////////////////////////////////////////////
810+ // Populate column_map with HYBRID layout
811+ column_map_type column_map;
812+ column_map[0 ] = std::make_pair (0 , 0 );
813+ column_map[1 ] = std::make_pair (1 , 0 );
814+ column_map[2 ] = std::make_pair (1 , 1 );
815+ column_map[3 ] = std::make_pair (2 , 0 );
816+ column_map[4 ] = std::make_pair (2 , 1 );
817+ column_map[5 ] = std::make_pair (2 , 2 );
818+
819+ auto database_oid = table->GetDatabaseOid ();
820+ auto table_oid = table->GetOid ();
821+
822+ txn = txn_manager.BeginTransaction ();
823+ auto layout = catalog->CreateDefaultLayout (database_oid, table_oid,
824+ column_map, txn);
825+ EXPECT_NE (nullptr , layout);
826+ txn_manager.CommitTransaction (txn);
827+
828+ // ///////////////////////////////////////////////////////
829+ // Load in 200 tuples
830+ // ///////////////////////////////////////////////////////
831+ tuple_count = 200 ;
832+ oid_t prev_tuple_count = 100 ;
833+ txn = txn_manager.BeginTransaction ();
834+ for (oid_t row_id = 0 ; row_id < tuple_count; row_id++) {
835+ int populate_value = row_id + prev_tuple_count;
836+
837+ storage::Tuple tuple (table_schema_ptr, allocate);
838+
839+ for (oid_t col_id = 0 ; col_id < col_count; col_id++) {
840+ auto value = type::ValueFactory::GetIntegerValue (populate_value + col_id);
841+ tuple.SetValue (col_id, value, testing_pool);
842+ }
843+
844+ ItemPointer *index_entry_ptr = nullptr ;
845+ ItemPointer tuple_slot_id =
846+ table->InsertTuple (&tuple, txn, &index_entry_ptr);
847+
848+ EXPECT_TRUE (tuple_slot_id.block != INVALID_OID);
849+ EXPECT_TRUE (tuple_slot_id.offset != INVALID_OID);
850+
851+ txn_manager.PerformInsert (txn, tuple_slot_id, index_entry_ptr);
852+ }
853+
854+ txn_manager.CommitTransaction (txn);
855+
856+ // ///////////////////////////////////////////////////////
857+ // Do a seq scan on the table
858+ // ///////////////////////////////////////////////////////
859+
860+ // Reset Tuple Count
861+ tuple_count = tuple_count + prev_tuple_count;
862+ // Column ids to be scanned.
863+ std::vector<oid_t > column_ids;
864+ for (oid_t col_id = 0 ; col_id < col_count; col_id++) {
865+ column_ids.push_back (col_id);
866+ }
867+
868+
869+ // Setup the scan plan node
870+ planner::SeqScanPlan scan (table, nullptr , column_ids);
871+
872+ // Do binding
873+ planner::BindingContext context;
874+ scan.PerformBinding (context);
875+
876+ // Printing consumer
877+ codegen::BufferingConsumer buffer{column_ids, context};
878+
879+
880+ // COMPILE and execute
881+ CompileAndExecute (scan, buffer);
882+
883+ // Check that we got all the results
884+ const auto &results = buffer.GetOutputTuples ();
885+ EXPECT_EQ (results.size (), tuple_count);
886+
887+ for (oid_t tuple_id = 0 ; tuple_id < tuple_count; tuple_id++) {
888+ auto &tuple = results[tuple_id];
889+ int tuple_id_value = tuple_id;
890+ for (oid_t col_id = 0 ; col_id < col_count; col_id++) {
891+ auto value = type::ValueFactory::GetIntegerValue (tuple_id_value + col_id);
892+ EXPECT_EQ (CmpBool::CmpTrue, tuple.GetValue (col_id).CompareEquals (value));
893+ }
894+ }
895+ }
896+
719897} // namespace test
720898} // namespace peloton
0 commit comments