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