/*@brief return all the columns this index indexed * @param index_oid * @param txn Transaction * @return a vector of column oid(logical position) */ std::vector<oid_t> IndexCatalog::GetIndexedAttributes( oid_t index_oid, concurrency::Transaction *txn) { std::vector<oid_t> column_ids({6}); // Indexed attributes oid_t index_offset = 0; // Index of index_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); std::vector<oid_t> key_attrs; std::string temp; auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); PL_ASSERT(result_tiles->size() <= 1); // index_oid is unique if (result_tiles->size() != 0) { PL_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { temp = (*result_tiles)[0]->GetValue(0, 0).ToString(); } } LOG_TRACE("the string value for index keys is %s", temp.c_str()); // using " " as delimiter to split up string and turn into vector of oid_t std::stringstream os(temp.c_str()); // Turn the string into a stream. std::string tok; while (std::getline(os, tok, ' ')) { key_attrs.push_back(std::stoi(tok)); } LOG_TRACE("the size for indexed key is %lu", key_attrs.size()); return key_attrs; }
int64_t QueryMetricsCatalog::GetNumParams(concurrency::TransactionContext *txn, const std::string &name) { std::vector<oid_t> column_ids({ColumnId::NUM_PARAMS}); // num_params oid_t index_offset = IndexId::PRIMARY_KEY; // Primary key index std::vector<type::Value> values; values.push_back(type::ValueFactory::GetVarcharValue(name, nullptr).Copy()); auto result_tiles = GetResultWithIndexScan(txn, column_ids, index_offset, values); int64_t num_params = 0; PELOTON_ASSERT(result_tiles->size() <= 1); // unique if (result_tiles->size() != 0) { PELOTON_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { num_params = (*result_tiles)[0] ->GetValue(0, 0) .GetAs<int>(); // After projection left 1 column } } return num_params; }
stats::QueryMetric::QueryParamBuf QueryMetricsCatalog::GetParamTypes(concurrency::TransactionContext *txn, const std::string &name) { std::vector<oid_t> column_ids({ColumnId::PARAM_TYPES}); // param_types oid_t index_offset = IndexId::PRIMARY_KEY; // Primary key index std::vector<type::Value> values; values.push_back(type::ValueFactory::GetVarcharValue(name, nullptr).Copy()); values.push_back(type::ValueFactory::GetIntegerValue(database_oid_).Copy()); auto result_tiles = GetResultWithIndexScan(txn, column_ids, index_offset, values); stats::QueryMetric::QueryParamBuf param_types; PELOTON_ASSERT(result_tiles->size() <= 1); // unique if (result_tiles->size() != 0) { PELOTON_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { auto param_types_value = (*result_tiles)[0]->GetValue(0, 0); param_types.buf = const_cast<uchar *>( reinterpret_cast<const uchar *>(param_types_value.GetData())); param_types.len = param_types_value.GetLength(); } } return param_types; }
/* @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; }
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; }
std::unique_ptr<trigger::TriggerList> TriggerCatalog::GetTriggers( oid_t table_oid, concurrency::TransactionContext *txn) { // LOG_DEBUG("Get triggers for table %d", table_oid); // select trigger_name, fire condition, function_name, function_args std::vector<oid_t> column_ids( {ColumnId::TRIGGER_NAME, ColumnId::TRIGGER_TYPE, ColumnId::FIRE_CONDITION, ColumnId::FUNCTION_OID, ColumnId::FUNCTION_ARGS}); oid_t index_offset = IndexId::TABLE_KEY_1; std::vector<type::Value> values; // where database_oid = args.database_oid and table_oid = args.table_oid and // trigger_type = args.trigger_type values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); // the result is a vector of executor::LogicalTile auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); // carefull! the result tile could be null! // if (result_tiles == nullptr) { // LOG_INFO("no trigger on table %d", table_oid); // } else { // LOG_INFO("size of the result tiles = %lu", result_tiles->size()); // } // create the trigger list std::unique_ptr<trigger::TriggerList> new_trigger_list{ new trigger::TriggerList()}; if (result_tiles != nullptr) { for (unsigned int i = 0; i < result_tiles->size(); i++) { size_t tuple_count = (*result_tiles)[i]->GetTupleCount(); for (size_t j = 0; j < tuple_count; j++) { // create a new trigger instance trigger::Trigger new_trigger( (*result_tiles)[i]->GetValue(j, 0).ToString(), (*result_tiles)[i]->GetValue(j, 1).GetAs<int16_t>(), (*result_tiles)[i]->GetValue(j, 3).ToString(), (*result_tiles)[i]->GetValue(j, 4).ToString(), (*result_tiles)[i]->GetValue(j, 2).GetData()); new_trigger_list->AddTrigger(new_trigger); } } } return new_trigger_list; }
/*@brief get all index records from the same table * this function may be useful when calling DropTable * @param table_oid * @param txn Transaction * @return a vector of index oid */ std::vector<oid_t> IndexCatalog::GetIndexOids(oid_t table_oid, concurrency::Transaction *txn) { std::vector<oid_t> column_ids({0}); // index_oid oid_t index_offset = 2; // Index of table_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); std::vector<oid_t> index_oids; for (auto &tile : (*result_tiles)) { for (auto tuple_id : *tile) { index_oids.emplace_back( tile->GetValue(tuple_id, 0) .GetAs<oid_t>()); // After projection left 1 column } } return index_oids; }
/*@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(); }
bool IndexCatalog::IsUniqueKeys(oid_t index_oid, concurrency::Transaction *txn) { std::vector<oid_t> column_ids({5}); // unique_keys oid_t index_offset = 0; // Index of index_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); bool unique_keys = false; PL_ASSERT(result_tiles->size() <= 1); // index_oid is unique if (result_tiles->size() != 0) { PL_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { unique_keys = (*result_tiles)[0] ->GetValue(0, 0) .GetAs<bool>(); // After projection left 1 column } } return unique_keys; }
oid_t IndexCatalog::GetTableOid(oid_t index_oid, concurrency::Transaction *txn) { std::vector<oid_t> column_ids({2}); // table_oid oid_t index_offset = 0; // Index of index_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); oid_t table_oid = INVALID_OID; PL_ASSERT(result_tiles->size() <= 1); // table_oid is unique if (result_tiles->size() != 0) { PL_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { table_oid = (*result_tiles)[0] ->GetValue(0, 0) .GetAs<oid_t>(); // After projection left 1 column } } return table_oid; }
std::string IndexCatalog::GetIndexName(oid_t index_oid, concurrency::Transaction *txn) { std::vector<oid_t> column_ids({1}); // index_name oid_t index_offset = 0; // Index of index_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); std::string index_name; PL_ASSERT(result_tiles->size() <= 1); // index_oid is unique if (result_tiles->size() != 0) { PL_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { index_name = (*result_tiles)[0] ->GetValue(0, 0) .ToString(); // After projection left 1 column } } return index_name; }
oid_t TriggerCatalog::GetTriggerOid(std::string trigger_name, oid_t table_oid, concurrency::TransactionContext *txn) { std::vector<oid_t> column_ids({ColumnId::TRIGGER_OID}); oid_t index_offset = IndexId::NAME_TABLE_KEY_2; std::vector<type::Value> values; values.push_back(type::ValueFactory::GetVarcharValue(trigger_name).Copy()); values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); oid_t trigger_oid = INVALID_OID; if (result_tiles->size() == 0) { // LOG_INFO("trigger %s doesn't exist", trigger_name.c_str()); } else { // LOG_INFO("size of the result tiles = %lu", result_tiles->size()); PELOTON_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { trigger_oid = (*result_tiles)[0]->GetValue(0, 0).GetAs<oid_t>(); } } return trigger_oid; }
IndexConstraintType IndexCatalog::GetIndexConstraint( oid_t index_oid, concurrency::Transaction *txn) { std::vector<oid_t> column_ids({4}); // index_constraint oid_t index_offset = 0; // Index of index_oid std::vector<type::Value> values; values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); auto result_tiles = GetResultWithIndexScan(column_ids, index_offset, values, txn); IndexConstraintType index_constraint = IndexConstraintType::INVALID; PL_ASSERT(result_tiles->size() <= 1); // index_oid is unique if (result_tiles->size() != 0) { PL_ASSERT((*result_tiles)[0]->GetTupleCount() <= 1); if ((*result_tiles)[0]->GetTupleCount() != 0) { index_constraint = static_cast<IndexConstraintType>( (*result_tiles)[0] ->GetValue(0, 0) .GetAs<int>()); // After projection left 1 column } } return index_constraint; }