/* * build right join output by adding null rows for every row from left tile * which doesn't have a match */ bool AbstractJoinExecutor::BuildRightJoinOutput() { while (right_matching_idx < no_matching_right_row_sets_.size()) { if (no_matching_right_row_sets_[right_matching_idx].empty()) { right_matching_idx++; continue; } std::unique_ptr<LogicalTile> output_tile(nullptr); auto right_tile = right_result_tiles_[right_matching_idx].get(); LogicalTile::PositionListsBuilder pos_lists_builder; if (left_result_tiles_.size() == 0) { // no tile information for left tile. construct a output tile from right // tile only output_tile = BuildOutputLogicalTile(nullptr, right_tile, proj_schema_); pos_lists_builder = LogicalTile::PositionListsBuilder( nullptr, &(right_tile->GetPositionLists())); } else { PL_ASSERT(left_result_tiles_.size() > 0); // construct the output tile from both children tiles auto left_tile = left_result_tiles_.front().get(); output_tile = BuildOutputLogicalTile(left_tile, right_tile); pos_lists_builder = LogicalTile::PositionListsBuilder(left_tile, right_tile); } // add rows with null values on the left for (auto right_row_itr : no_matching_right_row_sets_[right_matching_idx]) { pos_lists_builder.AddLeftNullRow(right_row_itr); } PL_ASSERT(pos_lists_builder.Size() > 0); output_tile->SetPositionListsAndVisibility(pos_lists_builder.Release()); SetOutput(output_tile.release()); right_matching_idx++; return true; } return false; }
void LogicalTile::MaterializeRowAtAtATime( const std::unordered_map<oid_t, oid_t> &old_to_new_cols, const std::unordered_map<storage::Tile *, std::vector<oid_t>> &tile_to_cols, storage::Tile *dest_tile) { /////////////////////////// // EACH PHYSICAL TILE /////////////////////////// // Copy over all data from each base tile. for (const auto &kv : tile_to_cols) { const std::vector<oid_t> &old_column_ids = kv.second; auto &schema = GetSchema(); oid_t new_tuple_id = 0; auto &column_position_lists = GetPositionLists(); // Get old column information std::vector<oid_t> old_column_position_idxs; std::vector<size_t> old_column_offsets; std::vector<ValueType> old_column_types; std::vector<bool> old_is_inlineds; std::vector<storage::Tile *> old_tiles; // Get new column information std::vector<size_t> new_column_offsets; std::vector<bool> new_is_inlineds; std::vector<size_t> new_column_lengths; // Amortize schema lookups once per column for (oid_t old_col_id : old_column_ids) { auto &column_info = schema[old_col_id]; // Get the position list old_column_position_idxs.push_back(column_info.position_list_idx); // Get old column information storage::Tile *old_tile = column_info.base_tile.get(); old_tiles.push_back(old_tile); auto old_schema = old_tile->GetSchema(); oid_t old_column_id = column_info.origin_column_id; const size_t old_column_offset = old_schema->GetOffset(old_column_id); old_column_offsets.push_back(old_column_offset); const ValueType old_column_type = old_schema->GetType(old_column_id); old_column_types.push_back(old_column_type); const bool old_is_inlined = old_schema->IsInlined(old_column_id); old_is_inlineds.push_back(old_is_inlined); // Old to new column mapping auto it = old_to_new_cols.find(old_col_id); assert(it != old_to_new_cols.end()); // Get new column information oid_t new_column_id = it->second; auto new_schema = dest_tile->GetSchema(); const size_t new_column_offset = new_schema->GetOffset(new_column_id); new_column_offsets.push_back(new_column_offset); const bool new_is_inlined = new_schema->IsInlined(new_column_id); new_is_inlineds.push_back(new_is_inlined); const size_t new_column_length = new_schema->GetAppropriateLength(new_column_id); new_column_lengths.push_back(new_column_length); } assert(new_column_offsets.size() == old_column_ids.size()); /////////////////////////// // EACH TUPLE /////////////////////////// // Copy all values in the tuple to the physical tile // This uses fast getter and setter functions for (oid_t old_tuple_id : *this) { /////////////////////////// // EACH COLUMN /////////////////////////// // Go over each column in given base physical tile oid_t col_itr = 0; for (oid_t old_col_id : old_column_position_idxs) { auto &column_position_list = column_position_lists[old_col_id]; oid_t base_tuple_id = column_position_list[old_tuple_id]; auto value = old_tiles[col_itr]->GetValueFast( base_tuple_id, old_column_offsets[col_itr], old_column_types[col_itr], old_is_inlineds[col_itr]); LOG_TRACE("Old Tuple : %u Column : %u ", old_tuple_id, old_col_id); LOG_TRACE("New Tuple : %u Column : %lu ", new_tuple_id, new_column_offsets[col_itr]); dest_tile->SetValueFast( value, new_tuple_id, new_column_offsets[col_itr], new_is_inlineds[col_itr], new_column_lengths[col_itr]); // Go to next column col_itr++; } // Go to next tuple new_tuple_id++; } } }