示例#1
0
/*
 * 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;
}
示例#2
0
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++;
    }
  }
}