Tile *Tile::CopyTile(BackendType backend_type) { auto schema = GetSchema(); bool tile_columns_inlined = schema->IsInlined(); auto allocated_tuple_count = GetAllocatedTupleCount(); // Create a shallow copy of the old tile TileGroupHeader *new_header = GetHeader(); Tile *new_tile = TileFactory::GetTile( backend_type, INVALID_OID, INVALID_OID, INVALID_OID, INVALID_OID, new_header, *schema, tile_group, allocated_tuple_count); PL_MEMCPY(static_cast<void *>(new_tile->data), static_cast<void *>(data), tile_size); // Do a deep copy if some column is uninlined, so that // the values in that column point to the new pool if (!tile_columns_inlined) { auto uninlined_col_cnt = schema->GetUninlinedColumnCount(); // Go over each uninlined column, making a deep copy for (oid_t col_itr = 0; col_itr < uninlined_col_cnt; col_itr++) { auto uninlined_col_offset = schema->GetUninlinedColumn(col_itr); // Copy the column over to the new tile group for (oid_t tuple_itr = 0; tuple_itr < allocated_tuple_count; tuple_itr++) { type::Value val = (new_tile->GetValue(tuple_itr, uninlined_col_offset)); new_tile->SetValue(val, tuple_itr, uninlined_col_offset); } } } return new_tile; }
// Compare two schemas bool Schema::operator==(const Schema &other) const { if (other.GetColumnCount() != GetColumnCount() || other.GetUninlinedColumnCount() != GetUninlinedColumnCount() || other.IsInlined() != IsInlined()) { return false; } for (oid_t column_itr = 0; column_itr < other.GetColumnCount(); column_itr++) { const Column &column_info = other.GetColumn(column_itr); const Column &other_column_info = GetColumn(column_itr); if (column_info != other_column_info) { return false; } } return true; }
void LogicalTile::MaterializeColumnAtATime( 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; /////////////////////////// // EACH COLUMN /////////////////////////// // Go over each column in given base physical tile for (oid_t old_col_id : old_column_ids) { auto &column_info = GetColumnInfo(old_col_id); // Amortize schema lookups once per column storage::Tile *old_tile = column_info.base_tile.get(); auto old_schema = old_tile->GetSchema(); // Get old column information oid_t old_column_id = column_info.origin_column_id; const size_t old_column_offset = old_schema->GetOffset(old_column_id); const ValueType old_column_type = old_schema->GetType(old_column_id); const bool old_is_inlined = old_schema->IsInlined(old_column_id); // 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); const bool new_is_inlined = new_schema->IsInlined(new_column_id); const size_t new_column_length = new_schema->GetAppropriateLength(new_column_id); // Get the position list auto &column_position_list = GetPositionList(column_info.position_list_idx); oid_t new_tuple_id = 0; // Copy all values in the column to the physical tile // This uses fast getter and setter functions /////////////////////////// // EACH TUPLE /////////////////////////// for (oid_t old_tuple_id : *this) { oid_t base_tuple_id = column_position_list[old_tuple_id]; auto value = old_tile->GetValueFast(base_tuple_id, old_column_offset, old_column_type, old_is_inlined); LOG_TRACE("Old Tuple : %u Column : %u ", old_tuple_id, old_col_id); LOG_TRACE("New Tuple : %u Column : %u ", new_tuple_id, new_column_id); dest_tile->SetValueFast(value, new_tuple_id, new_column_offset, new_is_inlined, new_column_length); // Go to next tuple new_tuple_id++; } } } }
void MaterializeRowAtAtATime( LogicalTile *source_tile, 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 = source_tile->GetSchema(); oid_t new_tuple_id = 0; auto &column_position_lists = source_tile->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 : *source_tile) { /////////////////////////// // 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 : %lu Column : %lu ", old_tuple_id, old_col_id); LOG_TRACE("New Tuple : %lu 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++; } } }
CreatePlan::CreatePlan(parser::CreateStatement *parse_tree) { table_name = parse_tree->GetTableName(); database_name = parse_tree->GetDatabaseName(); std::vector<catalog::Column> columns; std::vector<catalog::Constraint> column_contraints; if (parse_tree->type == parse_tree->CreateType::kTable) { create_type = CreateType::TABLE; for (auto col : *parse_tree->columns) { // TODO: Currently, the parser will parse the foreign key constraint and // put it into a ColumnDefinition. Later when we implement constraint // we may need to change this. Just skip foreign key constraint for now if (col->type == parser::ColumnDefinition::FOREIGN) continue; type::TypeId val = col->GetValueType(col->type); LOG_TRACE("Column name: %s; Is primary key: %d", col->name, col->primary); // Check main constraints if (col->primary) { catalog::Constraint constraint(ConstraintType::PRIMARY, "con_primary"); column_contraints.push_back(constraint); LOG_TRACE("Added a primary key constraint on column \"%s\"", col->name); } if (col->not_null) { catalog::Constraint constraint(ConstraintType::NOTNULL, "con_not_null"); column_contraints.push_back(constraint); } auto column = catalog::Column(val, type::Type::GetTypeSize(val), std::string(col->name), false); if (!column.IsInlined()) { column.SetLength(col->varlen); } for (auto con : column_contraints) { column.AddConstraint(con); } column_contraints.clear(); columns.push_back(column); } catalog::Schema *schema = new catalog::Schema(columns); table_schema = schema; } if (parse_tree->type == parse_tree->CreateType::kIndex) { create_type = CreateType::INDEX; index_name = std::string(parse_tree->index_name); table_name = std::string(parse_tree->GetTableName()); // This holds the attribute names. // This is a fix for a bug where // The vector<char*>* items gets deleted when passed // To the Executor. std::vector<std::string> index_attrs_holder; for (auto attr : *parse_tree->index_attrs) { index_attrs_holder.push_back(attr); } index_attrs = index_attrs_holder; index_type = parse_tree->index_type; unique = parse_tree->unique; } // TODO check type CreateType::kDatabase }