/* @brief First try get cached object from transaction cache. If cache miss, * construct database object from pg_database, and insert into the * cache. */ std::shared_ptr<DatabaseCatalogObject> DatabaseCatalog::GetDatabaseObject( const std::string &database_name, concurrency::TransactionContext *txn) { if (txn == nullptr) { throw CatalogException("Transaction is invalid!"); } // try get from cache auto database_object = txn->catalog_cache.GetDatabaseObject(database_name); if (database_object) return database_object; // cache miss, get from pg_database std::vector<oid_t> column_ids(all_column_ids); oid_t index_offset = IndexId::SKEY_DATABASE_NAME; // Index of database_name std::vector<type::Value> values; values.push_back( type::ValueFactory::GetVarcharValue(database_name, nullptr).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); if (result_tiles->size() == 1 && (*result_tiles)[0]->GetTupleCount() == 1) { auto database_object = std::make_shared<DatabaseCatalogObject>((*result_tiles)[0].get(), txn); if (database_object) { // insert into cache bool success = txn->catalog_cache.InsertDatabaseObject(database_object); PELOTON_ASSERT(success == true); (void)success; } return database_object; } // return empty object if not found return nullptr; }
std::shared_ptr<DatabaseCatalogObject> DatabaseCatalog::GetDatabaseObject( oid_t database_oid, concurrency::TransactionContext *txn) { if (txn == nullptr) { throw CatalogException("Transaction is invalid!"); } // try get from cache auto database_object = txn->catalog_cache.GetDatabaseObject(database_oid); if (database_object) return database_object; // cache miss, get from pg_database std::vector<oid_t> column_ids(all_column_ids); oid_t index_offset = IndexId::PRIMARY_KEY; // Index of database_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); if (result_tiles->size() == 1 && (*result_tiles)[0]->GetTupleCount() == 1) { auto database_object = std::make_shared<DatabaseCatalogObject>((*result_tiles)[0].get(), txn); // insert into cache bool success = txn->catalog_cache.InsertDatabaseObject(database_object); PELOTON_ASSERT(success == true); (void)success; return database_object; } else { LOG_DEBUG("Found %lu database tiles with oid %u", result_tiles->size(), database_oid); } // return empty object if not found return nullptr; }
/** * @brief CreateDatabase with INVALID OID * It MUST return false */ void BridgeTest::DDL_CreateDatabase_TEST_WITH_INVALID_OID() { bool status = DDLDatabase::CreateDatabase(INVALID_OID); // CHECK :: status must be false if (status != false) throw CatalogException("Could create database"); LOG_TRACE(":::::: %s DONE", __func__); }
/* Find a database using its oid from storage layer, * throw exception if not exists * */ Database *StorageManager::GetDatabaseWithOid( oid_t database_oid) const { for (auto database : databases_) if (database->GetOid() == database_oid) return database; throw CatalogException("Database with oid = " + std::to_string(database_oid) + " is not found"); return nullptr; }
/** * @brief CreateDatabase with VALID OID * It MUST return true */ void BridgeTest::DDL_CreateDatabase_TEST_WITH_VALID_OID() { bool status = DDLDatabase::CreateDatabase(12345); // CHECK :: status must be true if (status == false) throw CatalogException("Could not create database"); status = DDLDatabase::DropDatabase(12345); PL_ASSERT(status); LOG_TRACE(":::::: %s DONE", __func__); }
std::shared_ptr<IndexCatalogEntry> IndexCatalog::GetIndexCatalogEntry( concurrency::TransactionContext *txn, const std::string &database_name, const std::string &schema_name, const std::string &index_name) { if (txn == nullptr) { throw CatalogException("Transaction is invalid!"); } // try get from cache auto index_object = txn->catalog_cache.GetCachedIndexObject(database_name, schema_name, index_name); if (index_object) { return index_object; } // cache miss, get from pg_index std::vector<oid_t> column_ids(all_column_ids); oid_t index_offset = IndexId::SKEY_INDEX_NAME; // Index of index_name & schema_name std::vector<type::Value> values; values.push_back( type::ValueFactory::GetVarcharValue(index_name, nullptr).Copy()); values.push_back( type::ValueFactory::GetVarcharValue(schema_name, nullptr).Copy()); auto result_tiles = GetResultWithIndexScan(txn, column_ids, index_offset, values); if (result_tiles->size() == 1 && (*result_tiles)[0]->GetTupleCount() == 1) { auto index_object = std::make_shared<IndexCatalogEntry>((*result_tiles)[0].get()); // fetch all indexes into table object (cannot use the above index object) auto pg_table = Catalog::GetInstance() ->GetSystemCatalogs(database_oid_) ->GetTableCatalog(); auto table_object = pg_table->GetTableCatalogEntry(txn, index_object->GetTableOid()); PELOTON_ASSERT(table_object && table_object->GetTableOid() == index_object->GetTableOid()); return table_object->GetIndexCatalogEntry(index_name); } else { LOG_DEBUG("Found %lu index with name %s", result_tiles->size(), index_name.c_str()); } // return empty object if not found return nullptr; }
/** * @brief Create a sample unique key index * @params table_name table name new index will belong to * @params index_oid index oid */ void BridgeTest::CreateSampleUniqueIndex(std::string table_name, oid_t index_oid) { bool status; std::vector<std::string> key_column_names; key_column_names.push_back("time"); IndexInfo *index_info; index_info = new IndexInfo(table_name + "_key", index_oid, table_name, INDEX_TYPE_BTREE, INDEX_CONSTRAINT_TYPE_UNIQUE, true, key_column_names); status = DDLIndex::CreateIndex(*index_info); if (status == false) throw CatalogException("Could not create index"); }
std::shared_ptr<index::Index> DataTable::GetIndexWithOid( const oid_t &index_oid) { std::shared_ptr<index::Index> ret_index; auto index_count = indexes_.GetSize(); for (std::size_t index_itr = 0; index_itr < index_count; index_itr++) { ret_index = indexes_.Find(index_itr); if (ret_index != nullptr && ret_index->GetOid() == index_oid) { break; } } if (ret_index == nullptr) { throw CatalogException("No index with oid = " + std::to_string(index_oid) + " is found"); } return ret_index; }
/*@brief get all index records from the same table * this function may be useful when calling DropTable * @param table_oid * @param txn TransactionContext * @return a vector of index catalog objects */ const std::unordered_map<oid_t, std::shared_ptr<IndexCatalogEntry>> IndexCatalog::GetIndexCatalogEntries( concurrency::TransactionContext *txn, oid_t table_oid) { if (txn == nullptr) { throw CatalogException("Transaction is invalid!"); } // try get from cache auto pg_table = Catalog::GetInstance() ->GetSystemCatalogs(database_oid_) ->GetTableCatalog(); auto table_object = pg_table->GetTableCatalogEntry(txn, table_oid); PELOTON_ASSERT(table_object && table_object->GetTableOid() == table_oid); auto index_objects = table_object->GetIndexCatalogEntries(true); if (index_objects.empty() == false) return index_objects; // cache miss, get from pg_index std::vector<oid_t> column_ids(all_column_ids); oid_t index_offset = IndexId::SKEY_TABLE_OID; // Index of table_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); auto result_tiles = GetResultWithIndexScan(txn, column_ids, index_offset, values); for (auto &tile : (*result_tiles)) { for (auto tuple_id : *tile) { auto index_object = std::make_shared<IndexCatalogEntry>(tile.get(), tuple_id); table_object->InsertIndexCatalogEntry(index_object); } } return table_object->GetIndexCatalogEntries(); }
/** * @brief Create a sample foreign key * @params pktable_oid pktable oid * @params pktable_name pktable name * @params column column * @params table_oid table oid that foreign key will belong to */ void BridgeTest::CreateSampleForeignKey(oid_t pktable_oid, std::string pktable_name, std::vector<catalog::Column> &columns, oid_t table_oid) { bool status; // Create a sample table that has primary key index status = DDLTable::CreateTable(pktable_oid, pktable_name, columns); PL_ASSERT(status); std::vector<std::string> pk_column_names; std::vector<std::string> fk_column_names; pk_column_names.push_back("name"); fk_column_names.push_back("salary"); std::vector<catalog::ForeignKey> foreign_keys; catalog::ForeignKey *foreign_key = new catalog::ForeignKey(pktable_oid, pk_column_names, {1}, fk_column_names, {3}, 'r', 'c', "THIS_IS_FOREIGN_CONSTRAINT"); foreign_keys.push_back(*foreign_key); // Current table ----> reference table status = DDLTable::SetReferenceTables(foreign_keys, table_oid); if (status == false) throw CatalogException("Could not create sample foreign key"); }