Beispiel #1
0
TEST_F(CatalogTests, TableObject) {
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();

  auto table_object = catalog::Catalog::GetInstance()->GetTableObject(
      "EMP_DB", "department_table", txn);

  auto index_objects = table_object->GetIndexObjects();
  auto column_objects = table_object->GetColumnObjects();

  EXPECT_EQ(1, index_objects.size());
  EXPECT_EQ(2, column_objects.size());

  EXPECT_EQ(table_object->GetTableOid(), column_objects[0]->GetTableOid());
  EXPECT_EQ("id", column_objects[0]->GetColumnName());
  EXPECT_EQ(0, column_objects[0]->GetColumnId());
  EXPECT_EQ(0, column_objects[0]->GetColumnOffset());
  EXPECT_EQ(type::TypeId::INTEGER, column_objects[0]->GetColumnType());
  EXPECT_TRUE(column_objects[0]->IsInlined());
  EXPECT_TRUE(column_objects[0]->IsPrimary());
  EXPECT_FALSE(column_objects[0]->IsNotNull());

  EXPECT_EQ(table_object->GetTableOid(), column_objects[1]->GetTableOid());
  EXPECT_EQ("name", column_objects[1]->GetColumnName());
  EXPECT_EQ(1, column_objects[1]->GetColumnId());
  EXPECT_EQ(4, column_objects[1]->GetColumnOffset());
  EXPECT_EQ(type::TypeId::VARCHAR, column_objects[1]->GetColumnType());
  EXPECT_TRUE(column_objects[1]->IsInlined());
  EXPECT_FALSE(column_objects[1]->IsPrimary());
  EXPECT_FALSE(column_objects[1]->IsNotNull());

  txn_manager.CommitTransaction(txn);
}
Beispiel #2
0
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;
}
Beispiel #3
0
TEST_F(CatalogTests, TableObject) {
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();

  auto table_object = catalog::Catalog::GetInstance()->GetTableObject(
      "emp_db", DEFAULT_SCHEMA_NAME, "department_table", txn);

  auto index_objects = table_object->GetIndexObjects();
  auto column_objects = table_object->GetColumnObjects();

  EXPECT_EQ(1, index_objects.size());
  EXPECT_EQ(2, column_objects.size());

  EXPECT_EQ(table_object->GetTableOid(), column_objects[0]->GetTableOid());
  EXPECT_EQ("id", column_objects[0]->GetColumnName());
  EXPECT_EQ(0, column_objects[0]->GetColumnId());
  EXPECT_EQ(0, column_objects[0]->GetColumnOffset());
  EXPECT_EQ(type::TypeId::INTEGER, column_objects[0]->GetColumnType());
  EXPECT_TRUE(column_objects[0]->IsInlined());
  EXPECT_TRUE(column_objects[0]->IsPrimary());
  EXPECT_FALSE(column_objects[0]->IsNotNull());

  EXPECT_EQ(table_object->GetTableOid(), column_objects[1]->GetTableOid());
  EXPECT_EQ("name", column_objects[1]->GetColumnName());
  EXPECT_EQ(1, column_objects[1]->GetColumnId());
  EXPECT_EQ(4, column_objects[1]->GetColumnOffset());
  EXPECT_EQ(type::TypeId::VARCHAR, column_objects[1]->GetColumnType());
  EXPECT_TRUE(column_objects[1]->IsInlined());
  EXPECT_FALSE(column_objects[1]->IsPrimary());
  EXPECT_FALSE(column_objects[1]->IsNotNull());

  // update pg_table SET version_oid = 1 where table_name = department_table
  oid_t department_table_oid = table_object->GetTableOid();
  auto pg_table = catalog::Catalog::GetInstance()
                      ->GetSystemCatalogs(table_object->GetDatabaseOid())
                      ->GetTableCatalog();
  bool update_result = pg_table->UpdateVersionId(1, department_table_oid, txn);
  // get version id after update, invalidate old cache
  table_object = catalog::Catalog::GetInstance()->GetTableObject(
      "emp_db", DEFAULT_SCHEMA_NAME, "department_table", txn);
  uint32_t version_oid = table_object->GetVersionId();
  EXPECT_NE(department_table_oid, INVALID_OID);
  EXPECT_EQ(update_result, true);
  EXPECT_EQ(version_oid, 1);

  txn_manager.CommitTransaction(txn);
}
Beispiel #4
0
// { ----- begin ID methods -----
NS_IMETHODIMP
morkTable::GetOid(nsIMdbEnv* mev,
  mdbOid* outOid) // read object identity
{
  morkEnv* ev = morkEnv::FromMdbEnv(mev);
  GetTableOid(ev, outOid);
  return NS_OK;
}
Beispiel #5
0
/* @brief   evict table catalog object from cache
 * @param   table_name
 * @return  true if table_name is found and evicted; false if not found
 */
bool DatabaseCatalogObject::EvictTableObject(const std::string &table_name,
                                             const std::string &schema_name) {
  std::string key = schema_name + "." + table_name;
  // find table name from table name cache
  auto it = table_name_cache.find(key);
  if (it == table_name_cache.end()) {
    return false;  // table name not found in cache
  }

  auto table_object = it->second;
  PELOTON_ASSERT(table_object);
  table_name_cache.erase(it);
  table_objects_cache.erase(table_object->GetTableOid());
  return true;
}
Beispiel #6
0
bool IndexCatalog::DeleteIndex(concurrency::TransactionContext *txn,
                               oid_t database_oid,
                               oid_t index_oid) {
  oid_t index_offset = IndexId::PRIMARY_KEY;  // Index of index_oid
  std::vector<type::Value> values;
  values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy());

  auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid,
                                                              index_oid);
  if (index_object) {
    auto table_object =
        txn->catalog_cache.GetCachedTableObject(database_oid,
                                                index_object->GetTableOid());
    table_object->EvictAllIndexCatalogEntries();
  }

  return DeleteWithIndexScan(txn, index_offset, values);
}
Beispiel #7
0
/*@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();
}
Beispiel #8
0
TEST_F(CatalogTests, LayoutCatalogTest) {
  // This test creates a table, changes its layout.
  // Create another additional layout.
  // Ensure that default is not changed.
  // Drops layout and verifies that the default_layout is reset.
  // It also queries pg_layout to ensure that the entry is removed.

  auto db_name = "temp_db";
  auto table_name = "temp_table";
  auto catalog = catalog::Catalog::GetInstance();
  // Create database.
  auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
  auto txn = txn_manager.BeginTransaction();
  EXPECT_EQ(ResultType::SUCCESS, catalog->CreateDatabase(db_name, txn));

  // Create table.
  auto val0 = catalog::Column(type::TypeId::INTEGER,
                              type::Type::GetTypeSize(type::TypeId::INTEGER),
                              "val0", true);
  auto val1 = catalog::Column(type::TypeId::INTEGER,
                              type::Type::GetTypeSize(type::TypeId::INTEGER),
                              "val1", true);
  auto val2 = catalog::Column(type::TypeId::INTEGER,
                              type::Type::GetTypeSize(type::TypeId::INTEGER),
                              "val2", true);
  auto val3 = catalog::Column(type::TypeId::INTEGER,
                              type::Type::GetTypeSize(type::TypeId::INTEGER),
                              "val3", true);
  std::unique_ptr<catalog::Schema> table_schema(
      new catalog::Schema({val0, val1, val2, val3}));
  EXPECT_EQ(ResultType::SUCCESS,
            catalog->CreateTable(db_name, DEFAULT_SCHEMA_NAME, table_name,
                                 std::move(table_schema), txn));
  txn_manager.CommitTransaction(txn);

  txn = txn_manager.BeginTransaction();
  auto database_oid =
      catalog->GetDatabaseObject(db_name, txn)->GetDatabaseOid();
  auto table_object =
      catalog->GetTableObject(db_name, DEFAULT_SCHEMA_NAME, table_name, txn);
  auto table_oid = table_object->GetTableOid();
  auto table =
      catalog->GetTableWithName(db_name, DEFAULT_SCHEMA_NAME, table_name, txn);
  txn_manager.CommitTransaction(txn);

  // Change default layout.

  std::map<oid_t, std::pair<oid_t, oid_t>> default_map;
  default_map[0] = std::make_pair(0, 0);
  default_map[1] = std::make_pair(0, 1);
  default_map[2] = std::make_pair(1, 0);
  default_map[3] = std::make_pair(1, 1);

  txn = txn_manager.BeginTransaction();
  auto default_layout =
      catalog->CreateDefaultLayout(database_oid, table_oid, default_map, txn);
  txn_manager.CommitTransaction(txn);
  EXPECT_NE(nullptr, default_layout);

  // Create additional layout.
  std::map<oid_t, std::pair<oid_t, oid_t>> non_default_map;
  non_default_map[0] = std::make_pair(0, 0);
  non_default_map[1] = std::make_pair(0, 1);
  non_default_map[2] = std::make_pair(1, 0);
  non_default_map[3] = std::make_pair(1, 1);

  txn = txn_manager.BeginTransaction();
  auto other_layout =
      catalog->CreateLayout(database_oid, table_oid, non_default_map, txn);
  txn_manager.CommitTransaction(txn);

  // Check that the default layout is still the same.
  EXPECT_NE(*other_layout.get(), table->GetDefaultLayout());

  // Drop the default layout.
  auto default_layout_oid = default_layout->GetOid();
  txn = txn_manager.BeginTransaction();
  EXPECT_EQ(ResultType::SUCCESS, catalog->DropLayout(database_oid, table_oid,
                                                     default_layout_oid, txn));
  txn_manager.CommitTransaction(txn);

  // Check that default layout is reset and set to row_store.
  EXPECT_NE(*default_layout.get(), table->GetDefaultLayout());
  EXPECT_TRUE(table->GetDefaultLayout().IsRowStore());

  // Query pg_layout to ensure that the entry is dropped
  txn = txn_manager.BeginTransaction();
  auto pg_layout = catalog->GetSystemCatalogs(database_oid)->GetLayoutCatalog();
  EXPECT_EQ(nullptr,
            pg_layout->GetLayoutWithOid(table_oid, default_layout_oid, txn));

  // The additional layout must be present in pg_layout
  auto other_layout_oid = other_layout->GetOid();
  EXPECT_EQ(
      *(other_layout.get()),
      *(pg_layout->GetLayoutWithOid(table_oid, other_layout_oid, txn).get()));
  txn_manager.CommitTransaction(txn);

  // Drop database
  txn = txn_manager.BeginTransaction();
  catalog->DropDatabaseWithName(db_name, txn);
  txn_manager.CommitTransaction(txn);
}