From 39f68326bbfc901a73050f40ee9a8ee173d7c321 Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Mon, 11 Jun 2018 15:18:31 -0400 Subject: [PATCH 1/9] Initial checkin with the sequence code (without temporary tables) from #1345 Checking in the testing files from #1345 These should be the last files that we need from from #1345 This compiles and passes all the tests except for the sequence test (obviously) --- script/testing/junit/SequenceTest.java | 172 ++++++++++ src/catalog/catalog.cpp | 16 + src/catalog/catalog_cache.cpp | 83 +++++ src/catalog/database_catalog.cpp | 10 +- src/catalog/index_catalog.cpp | 8 +- src/catalog/sequence_catalog.cpp | 307 ++++++++++++++++++ src/catalog/system_catalogs.cpp | 6 + src/catalog/table_catalog.cpp | 8 +- .../proxy/sequence_functions_proxy.cpp | 24 ++ src/codegen/type/bigint_type.cpp | 48 ++- src/common/internal_types.cpp | 16 + src/concurrency/transaction_context.cpp | 5 + src/executor/create_executor.cpp | 41 +++ src/executor/drop_executor.cpp | 33 ++ src/expression/function_expression.cpp | 8 +- src/function/sequence_functions.cpp | 150 +++++++++ src/include/catalog/catalog_cache.h | 39 ++- src/include/catalog/catalog_defaults.h | 6 +- src/include/catalog/sequence_catalog.h | 225 +++++++++++++ src/include/catalog/system_catalogs.h | 11 + .../codegen/proxy/sequence_functions_proxy.h | 28 ++ src/include/common/exception.h | 13 +- src/include/common/internal_types.h | 10 +- src/include/concurrency/transaction_context.h | 14 +- src/include/executor/create_executor.h | 2 + src/include/executor/drop_executor.h | 3 + src/include/function/sequence_functions.h | 41 +++ src/include/parser/create_statement.h | 18 +- src/include/parser/drop_statement.h | 13 +- src/include/parser/parsenodes.h | 12 + src/include/parser/postgresparser.h | 11 + src/include/planner/create_plan.h | 21 +- src/include/planner/drop_plan.h | 6 + src/include/planner/plan_util.h | 4 +- src/network/postgres_protocol_handler.cpp | 1 + src/parser/create_statement.cpp | 6 + src/parser/drop_statement.cpp | 8 + src/parser/postgresparser.cpp | 84 +++++ src/planner/create_plan.cpp | 12 + src/planner/drop_plan.cpp | 7 + src/planner/plan_util.cpp | 10 +- test/function/sequence_functions_test.cpp | 109 +++++++ test/parser/postgresparser_test.cpp | 49 +++ test/planner/plan_util_test.cpp | 26 +- 44 files changed, 1670 insertions(+), 54 deletions(-) create mode 100644 script/testing/junit/SequenceTest.java create mode 100644 src/catalog/sequence_catalog.cpp create mode 100644 src/codegen/proxy/sequence_functions_proxy.cpp create mode 100644 src/function/sequence_functions.cpp create mode 100644 src/include/catalog/sequence_catalog.h create mode 100644 src/include/codegen/proxy/sequence_functions_proxy.h create mode 100644 src/include/function/sequence_functions.h create mode 100644 test/function/sequence_functions_test.cpp diff --git a/script/testing/junit/SequenceTest.java b/script/testing/junit/SequenceTest.java new file mode 100644 index 00000000000..07d9f30fac9 --- /dev/null +++ b/script/testing/junit/SequenceTest.java @@ -0,0 +1,172 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// SequenceTest.java +// +// Identification: script/testing/junit/SequenceTest.java +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +import java.sql.*; +import org.junit.*; +import org.postgresql.util.PSQLException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static junit.framework.TestCase.fail; + +public class SequenceTest extends PLTestBase { + private Connection conn1; + private Connection conn2; + + private static final String SQL_DROP_SEQ = + "DROP SEQUENCE seq;"; + + private static final String SQL_CREATE_SEQ = + "CREATE SEQUENCE seq;"; + + private static final String SQL_NEXTVAL = + "SELECT NEXTVAL('seq')"; + + private static final String SQL_CURRVAL = + "SELECT CURRVAL('seq')"; + + /** + * Test sequence functions for single-statment transactions + */ + @Test + public void test_SingleStmtTxn() throws SQLException { + conn1 = makeDefaultConnection(); + conn1.setAutoCommit(true); + Statement stmt1 = conn1.createStatement(); + + conn2 = makeDefaultConnection(); + conn2.setAutoCommit(true); + Statement stmt2 = conn2.createStatement(); + + // Create a sequence + stmt1.execute(SQL_CREATE_SEQ); + + // Check the sequence is visible by others + try { + stmt2.execute(SQL_CREATE_SEQ); + fail(); + } catch (PSQLException e) { } + + // Check currval cannot be called before nextval + try { + stmt1.execute(SQL_CURRVAL); + fail(); + } catch (PSQLException e) { } + + // Check functionality with conn1 + stmt1.execute(SQL_NEXTVAL); + ResultSet res1 = stmt1.executeQuery(SQL_CURRVAL); + res1.next(); + assertEquals(1, res1.getInt(1)); + assertNoMoreRows(res1); + + // Update should be visible to conn2 + stmt2.execute(SQL_NEXTVAL); + ResultSet res2 = stmt2.executeQuery(SQL_CURRVAL); + res2.next(); + assertEquals(2, res2.getInt(1)); + assertNoMoreRows(res2); + + // Currval should be session consistent + res1 = stmt1.executeQuery(SQL_CURRVAL); + res1.next(); + assertEquals(1, res1.getInt(1)); + assertNoMoreRows(res1); + + // Clean up + stmt1.close(); + conn1.close(); + stmt2.close(); + conn2.close(); + } + + /** + * Test sequence functions for multi-statment transactions + */ + @Test + public void test_MultiStmtTxn() throws SQLException { + conn1 = makeDefaultConnection(); + conn1.setAutoCommit(false); + Statement stmt1 = conn1.createStatement(); + + conn2 = makeDefaultConnection(); + conn2.setAutoCommit(false); + Statement stmt2 = conn2.createStatement(); + + // Check functionality with conn1 + stmt1.execute(SQL_NEXTVAL); + ResultSet res1 = stmt1.executeQuery(SQL_CURRVAL); + res1.next(); + assertEquals(3, res1.getInt(1)); + assertNoMoreRows(res1); + + // Update should be visible to conn2 + stmt2.execute(SQL_NEXTVAL); + ResultSet res2 = stmt2.executeQuery(SQL_CURRVAL); + res2.next(); + assertEquals(4, res2.getInt(1)); + assertNoMoreRows(res2); + + // Rollback transactions + conn1.rollback(); + conn2.rollback(); + + // Check sequence incremental will not rollback + conn1.setAutoCommit(true); + stmt1.execute(SQL_NEXTVAL); + res1 = stmt1.executeQuery(SQL_CURRVAL); + res1.next(); + assertEquals(5, res1.getInt(1)); + assertNoMoreRows(res1); + + // Clean up + stmt1.close(); + conn1.close(); + stmt2.close(); + conn2.close(); + } + + /** + * Test dropping sequence + */ + @Test + public void test_Drop_Seq() throws SQLException { + conn1 = makeDefaultConnection(); + conn1.setAutoCommit(true); + Statement stmt1 = conn1.createStatement(); + + conn2 = makeDefaultConnection(); + conn2.setAutoCommit(true); + Statement stmt2 = conn2.createStatement(); + + // Drop the sequence + stmt1.execute(SQL_DROP_SEQ); + + // Check the sequence is invisible to all conns + try { + stmt1.execute(SQL_CURRVAL); + fail(); + } catch (PSQLException e) { } + try { + stmt2.execute(SQL_CURRVAL); + fail(); + } catch (PSQLException e) { } + + // Check the same sequence can be created w/o exception + stmt2.execute(SQL_CREATE_SEQ); + + // Clean up + stmt1.close(); + conn1.close(); + stmt2.close(); + conn2.close(); + } +} diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 46f534dc84d..59fa42ce755 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -32,6 +32,8 @@ #include "function/date_functions.h" #include "function/numeric_functions.h" #include "function/old_engine_string_functions.h" +#include "function/string_functions.h" +#include "function/sequence_functions.h" #include "function/timestamp_functions.h" #include "index/index_factory.h" #include "settings/settings_manager.h" @@ -1308,6 +1310,20 @@ void Catalog::InitializeFunctions() { function::BuiltInFuncType{OperatorId::Like, function::OldEngineStringFunctions::Like}, txn); + // Sequence + AddBuiltinFunction( + "nextval", {type::TypeId::VARCHAR}, type::TypeId::INTEGER, + internal_lang, "Nextval", + function::BuiltInFuncType{OperatorId::Nextval, + function::SequenceFunctions::_Nextval}, + txn); + AddBuiltinFunction( + "currval", {type::TypeId::VARCHAR}, type::TypeId::INTEGER, + internal_lang, "Currval", + function::BuiltInFuncType{OperatorId::Currval, + function::SequenceFunctions::_Currval}, + txn); + /** * decimal functions diff --git a/src/catalog/catalog_cache.cpp b/src/catalog/catalog_cache.cpp index b97a55b975a..90f6aefbbb2 100644 --- a/src/catalog/catalog_cache.cpp +++ b/src/catalog/catalog_cache.cpp @@ -15,6 +15,7 @@ #include "catalog/catalog_cache.h" #include "catalog/database_catalog.h" +#include "catalog/sequence_catalog.h" #include "common/logger.h" namespace peloton { @@ -111,6 +112,14 @@ std::shared_ptr CatalogCache::GetDatabaseObject( return it->second; } +std::vector> CatalogCache::GetAllDatabaseObjects() { + std::vector> databases; + for (auto it : database_objects_cache) { + databases.push_back(it.second); + } + return (databases); +} + /*@brief search table catalog object from all cached database objects * @param table_oid * @return table catalog object; if not found return null @@ -152,5 +161,79 @@ std::shared_ptr CatalogCache::GetCachedIndexObject( return nullptr; } +/*@brief insert sequence catalog object into cache + * @param sequence_object + * @return false only if sequence already exists in cache or invalid + */ +bool CatalogCache::InsertSequenceObject( + std::shared_ptr sequence_object) { + if (!sequence_object || sequence_object->seq_oid == INVALID_OID) { + return false; // invalid object + } + + std::size_t hash_key = GetHashKey(sequence_object->seq_name, + sequence_object->db_oid); + + // check if already in cache + if (sequence_objects_cache.find(hash_key) != + sequence_objects_cache.end()) { + LOG_DEBUG("Sequence %s already exists in cache!", + sequence_object->seq_name.c_str()); + return false; + } + + sequence_objects_cache.insert( + std::make_pair(hash_key, sequence_object)); + return true; +} + +/*@brief evict sequence catalog object from cache + * @param sequence_name + * @param database_oid + * @return true if specified sequence is found and evicted; + * false if not found + */ +bool CatalogCache::EvictSequenceObject(const std::string & sequence_name, + oid_t database_oid) { + std::size_t hash_key = GetHashKey(sequence_name, database_oid); + + auto it = sequence_objects_cache.find(hash_key); + if (it == sequence_objects_cache.end()) { + return false; // sequence not found in cache + } + + auto sequence_object = it->second; + PELOTON_ASSERT(sequence_object); + sequence_objects_cache.erase(it); + return true; +} + +/*@brief get sequence catalog object from cache + * @param sequence_name + * @param database_oid + * @return sequence catalog object; if not found return object with invalid oid + */ +std::shared_ptr CatalogCache::GetSequenceObject( + const std::string & sequence_name, oid_t database_oid) { + std::size_t hash_key = GetHashKey(sequence_name, database_oid); + auto it = sequence_objects_cache.find(hash_key); + if (it == sequence_objects_cache.end()) { + return nullptr; + } + return it->second; +} + +/*@brief get the hash key given the sequence information + * @param sequence_name + * @param database_oid + * @return hash key + */ +std::size_t CatalogCache::GetHashKey(const std::string sequence_name, + oid_t database_oid) { + std::tuple key(sequence_name, database_oid); + boost::hash> key_hash; + return key_hash(key); +} + } // namespace catalog } // namespace peloton diff --git a/src/catalog/database_catalog.cpp b/src/catalog/database_catalog.cpp index fc0b81c64d0..a1dfd8571c1 100644 --- a/src/catalog/database_catalog.cpp +++ b/src/catalog/database_catalog.cpp @@ -314,7 +314,7 @@ bool DatabaseCatalog::DeleteDatabase(oid_t database_oid, values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); // evict cache - txn->catalog_cache.EvictDatabaseObject(database_oid); + txn->GetCatalogCache()->EvictDatabaseObject(database_oid); return DeleteWithIndexScan(index_offset, values, txn); } @@ -325,7 +325,7 @@ std::shared_ptr DatabaseCatalog::GetDatabaseObject( throw CatalogException("Transaction is invalid!"); } // try get from cache - auto database_object = txn->catalog_cache.GetDatabaseObject(database_oid); + auto database_object = txn->GetCatalogCache()->GetDatabaseObject(database_oid); if (database_object) return database_object; // cache miss, get from pg_database @@ -341,7 +341,7 @@ std::shared_ptr DatabaseCatalog::GetDatabaseObject( auto database_object = std::make_shared((*result_tiles)[0].get(), txn); // insert into cache - bool success = txn->catalog_cache.InsertDatabaseObject(database_object); + bool success = txn->GetCatalogCache()->InsertDatabaseObject(database_object); PELOTON_ASSERT(success == true); (void)success; return database_object; @@ -364,7 +364,7 @@ std::shared_ptr DatabaseCatalog::GetDatabaseObject( throw CatalogException("Transaction is invalid!"); } // try get from cache - auto database_object = txn->catalog_cache.GetDatabaseObject(database_name); + auto database_object = txn->GetCatalogCache()->GetDatabaseObject(database_name); if (database_object) return database_object; // cache miss, get from pg_database @@ -382,7 +382,7 @@ std::shared_ptr DatabaseCatalog::GetDatabaseObject( std::make_shared((*result_tiles)[0].get(), txn); if (database_object) { // insert into cache - bool success = txn->catalog_cache.InsertDatabaseObject(database_object); + bool success = txn->GetCatalogCache()->InsertDatabaseObject(database_object); PELOTON_ASSERT(success == true); (void)success; } diff --git a/src/catalog/index_catalog.cpp b/src/catalog/index_catalog.cpp index 5c66139e81f..371543175ad 100644 --- a/src/catalog/index_catalog.cpp +++ b/src/catalog/index_catalog.cpp @@ -174,11 +174,11 @@ bool IndexCatalog::DeleteIndex(oid_t database_oid, oid_t index_oid, values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid, - index_oid); + index_oid); if (index_object) { auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, - index_object->GetTableOid()); + index_object->GetTableOid()); table_object->EvictAllIndexObjects(); } @@ -192,7 +192,7 @@ std::shared_ptr IndexCatalog::GetIndexObject( } // try get from cache auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid, - index_oid); + index_oid); if (index_object) { return index_object; } @@ -235,7 +235,7 @@ std::shared_ptr IndexCatalog::GetIndexObject( // try get from cache auto index_object = txn->catalog_cache.GetCachedIndexObject(database_name, index_name, - schema_name); + schema_name); if (index_object) { return index_object; } diff --git a/src/catalog/sequence_catalog.cpp b/src/catalog/sequence_catalog.cpp new file mode 100644 index 00000000000..55c47069050 --- /dev/null +++ b/src/catalog/sequence_catalog.cpp @@ -0,0 +1,307 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_catalog.h +// +// Identification: src/catalog/sequence_catalog.cpp +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include + +#include "catalog/sequence_catalog.h" + +#include "catalog/catalog.h" +#include "catalog/database_catalog.h" +#include "catalog/table_catalog.h" +#include "common/internal_types.h" +#include "storage/data_table.h" +#include "type/value_factory.h" +#include "function/functions.h" +#include "planner/update_plan.h" +#include "executor/update_executor.h" +#include "executor/executor_context.h" +#include "optimizer/optimizer.h" +#include "parser/postgresparser.h" + +namespace peloton { +namespace catalog { + +/* @brief Get the nextval of the sequence + * @return the next value of the sequence. + * @exception throws SequenceException if the sequence exceeds the upper/lower + * limit. + */ +int64_t SequenceCatalogObject::GetNextVal() { + int64_t result = seq_curr_val; + seq_prev_val = result; + if (seq_increment > 0) { + // Check to see whether the nextval is out of bound + if ((seq_max >= 0 && seq_curr_val > seq_max - seq_increment) || + (seq_max < 0 && seq_curr_val + seq_increment > seq_max)) { + if (!seq_cycle) { + throw SequenceException( + StringUtil::Format( + "nextval: reached maximum value of sequence %s (%ld)", seq_name.c_str(), seq_max)); + } + seq_curr_val = seq_min; + } else + seq_curr_val += seq_increment; + } else { + // Check to see whether the nextval is out of bound + if ((seq_min < 0 && seq_curr_val < seq_min - seq_increment) || + (seq_min >= 0 && seq_curr_val + seq_increment < seq_min)) { + if (!seq_cycle) { + throw SequenceException( + StringUtil::Format( + "nextval: reached minimum value of sequence %s (%ld)", seq_name.c_str(), seq_min)); + } + seq_curr_val = seq_max; + } else + seq_curr_val += seq_increment; + } + + Catalog::GetInstance()->GetSystemCatalogs(db_oid) + ->GetSequenceCatalog() + ->UpdateNextVal(seq_oid, seq_curr_val, txn_); + return result; +} + +SequenceCatalog::SequenceCatalog(const std::string &database_name, + concurrency::TransactionContext *txn) + : AbstractCatalog("CREATE TABLE " + database_name + + "." CATALOG_SCHEMA_NAME "." SEQUENCE_CATALOG_NAME + " (" + "oid INT NOT NULL PRIMARY KEY, " + "sqdboid INT NOT NULL, " + "sqname VARCHAR NOT NULL, " + "sqinc BIGINT NOT NULL, " + "sqmax BIGINT NOT NULL, " + "sqmin BIGINT NOT NULL, " + "sqstart BIGINT NOT NULL, " + "sqcycle BOOLEAN NOT NULL, " + "sqval BIGINT NOT NULL);", + txn) { + Catalog::GetInstance()->CreateIndex( + database_name, CATALOG_SCHEMA_NAME, SEQUENCE_CATALOG_NAME, + {ColumnId::DATABSE_OID, ColumnId::SEQUENCE_NAME}, + SEQUENCE_CATALOG_NAME "_skey0", false, IndexType::BWTREE, txn); +} + +SequenceCatalog::~SequenceCatalog() {} + +/* @brief Insert the sequence by name. + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param seq_increment the increment per step of the sequence + * @param seq_max the max value of the sequence + * @param seq_min the min value of the sequence + * @param seq_start the start of the sequence + * @param seq_cycle whether the sequence cycles + * @param pool an instance of abstract pool + * @param txn current transaction + * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE + * otherwise. + * @exception throws SequenceException if the sequence already exists. + */ +bool SequenceCatalog::InsertSequence(oid_t database_oid, + std::string sequence_name, + int64_t seq_increment, int64_t seq_max, + int64_t seq_min, int64_t seq_start, + bool seq_cycle, type::AbstractPool *pool, + concurrency::TransactionContext *txn) { + LOG_DEBUG("Insert Sequence Database Oid: %u", database_oid); + LOG_DEBUG("Insert Sequence Sequence Name: %s", sequence_name.c_str()); + + ValidateSequenceArguments(seq_increment, seq_max, seq_min, seq_start); + if (GetSequence(database_oid, sequence_name, txn) != nullptr) { + throw SequenceException( + StringUtil::Format("Sequence %s already exists!", + sequence_name.c_str())); + } + + std::unique_ptr tuple( + new storage::Tuple(catalog_table_->GetSchema(), true)); + + auto val0 = type::ValueFactory::GetIntegerValue(GetNextOid()); + auto val1 = type::ValueFactory::GetIntegerValue(database_oid); + auto val2 = type::ValueFactory::GetVarcharValue(sequence_name); + auto val3 = type::ValueFactory::GetBigIntValue(seq_increment); + auto val4 = type::ValueFactory::GetBigIntValue(seq_max); + auto val5 = type::ValueFactory::GetBigIntValue(seq_min); + auto val6 = type::ValueFactory::GetBigIntValue(seq_start); + auto val7 = type::ValueFactory::GetBooleanValue(seq_cycle); + // When insert value, seqval = seq_start + auto val8 = type::ValueFactory::GetBigIntValue(seq_start); + + tuple->SetValue(ColumnId::SEQUENCE_OID, val0, pool); + tuple->SetValue(ColumnId::DATABSE_OID, val1, pool); + tuple->SetValue(ColumnId::SEQUENCE_NAME, val2, pool); + tuple->SetValue(ColumnId::SEQUENCE_INC, val3, pool); + tuple->SetValue(ColumnId::SEQUENCE_MAX, val4, pool); + tuple->SetValue(ColumnId::SEQUENCE_MIN, val5, pool); + tuple->SetValue(ColumnId::SEQUENCE_START, val6, pool); + tuple->SetValue(ColumnId::SEQUENCE_CYCLE, val7, pool); + tuple->SetValue(ColumnId::SEQUENCE_VALUE, val8, pool); + + // Insert the tuple + return InsertTuple(std::move(tuple), txn); +} + +/* @brief Delete the sequence by name. + * @param database_name the database name associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return ResultType::SUCCESS if the sequence exists, throw exception + * otherwise. + */ +ResultType SequenceCatalog::DropSequence(const std::string &database_name, + const std::string &sequence_name, + concurrency::TransactionContext *txn) { + if (txn == nullptr) { + throw CatalogException("Transaction is invalid!"); + } + + auto database_object = + Catalog::GetInstance()->GetDatabaseObject(database_name, txn); + + oid_t database_oid = database_object->GetDatabaseOid(); + + oid_t sequence_oid = Catalog::GetInstance() + ->GetSystemCatalogs(database_oid) + ->GetSequenceCatalog() + ->GetSequenceOid(sequence_name, database_oid, txn); + if (sequence_oid == INVALID_OID) { + throw SequenceException( + StringUtil::Format("Sequence %s does not exist!", + sequence_name.c_str())); + } + + LOG_INFO("sequence %d will be deleted!", sequence_oid); + + DeleteSequenceByName(sequence_name, database_oid, txn); + EvictSequenceNameCurrValCache(sequence_name); + + return ResultType::SUCCESS; +} + +/* @brief Delete the sequence by name. The sequence is guaranteed to exist. + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return The result of DeleteWithIndexScan. + */ +bool SequenceCatalog::DeleteSequenceByName( + const std::string &sequence_name, oid_t database_oid, + concurrency::TransactionContext *txn) { + oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; + std::vector values; + values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); + + return DeleteWithIndexScan(index_offset, values, txn); +} + +/* @brief get sequence from pg_sequence table + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return a SequenceCatalogObject if the sequence is found, nullptr otherwise + */ +std::shared_ptr SequenceCatalog::GetSequence( + oid_t database_oid, const std::string &sequence_name, + concurrency::TransactionContext *txn) { + std::vector column_ids( + {ColumnId::SEQUENCE_OID, ColumnId::SEQUENCE_START, + ColumnId::SEQUENCE_INC, ColumnId::SEQUENCE_MAX, + ColumnId::SEQUENCE_MIN, ColumnId::SEQUENCE_CYCLE, + ColumnId::SEQUENCE_VALUE}); + oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; + std::vector values; + values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); + + // the result is a vector of executor::LogicalTile + auto result_tiles = + GetResultWithIndexScan(column_ids, index_offset, values, txn); + // careful! the result tile could be null! + if (result_tiles == nullptr || result_tiles->size() == 0) { + LOG_INFO("no sequence on database %d and %s", database_oid, + sequence_name.c_str()); + return std::shared_ptr(nullptr); + } else { + LOG_INFO("size of the result tiles = %lu", result_tiles->size()); + } + + PELOTON_ASSERT(result_tiles->size() == 1); + size_t tuple_count = (*result_tiles)[0]->GetTupleCount(); + PELOTON_ASSERT(tuple_count == 1); + (void) tuple_count; + auto new_sequence = std::make_shared( + (*result_tiles)[0]->GetValue(0, 0).GetAs(), + database_oid, + sequence_name, + (*result_tiles)[0]->GetValue(0, 1).GetAs(), + (*result_tiles)[0]->GetValue(0, 2).GetAs(), + (*result_tiles)[0]->GetValue(0, 3).GetAs(), + (*result_tiles)[0]->GetValue(0, 4).GetAs(), + (*result_tiles)[0]->GetValue(0, 5).GetAs(), + (*result_tiles)[0]->GetValue(0, 6).GetAs(), txn); + + return new_sequence; +} + +/* @brief update the next value of the sequence in the underlying storage + * @param sequence_oid the sequence_oid of the sequence + * @param nextval the nextval of the sequence + * @param txn current transaction + * @return the result of the transaction + */ +bool SequenceCatalog::UpdateNextVal(oid_t sequence_oid, int64_t nextval, + concurrency::TransactionContext *txn){ + std::vector update_columns({SequenceCatalog::ColumnId::SEQUENCE_VALUE}); + std::vector update_values; + update_values.push_back(type::ValueFactory::GetBigIntValue(nextval).Copy()); + std::vector scan_values; + scan_values.push_back(type::ValueFactory::GetIntegerValue(sequence_oid).Copy()); + oid_t index_offset = SequenceCatalog::IndexId::PRIMARY_KEY; + + return UpdateWithIndexScan(update_columns, update_values, scan_values, index_offset, txn); +} + +/* @brief get sequence oid from pg_sequence table given sequence_name and + * database_oid + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return the oid_t of the sequence if the sequence is found, INVALID_OID + * otherwise + */ +oid_t SequenceCatalog::GetSequenceOid(std::string sequence_name, + oid_t database_oid, + concurrency::TransactionContext *txn) { + std::vector column_ids({ColumnId::SEQUENCE_OID}); + oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; + std::vector values; + values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); + + // the result is a vector of executor::LogicalTile + auto result_tiles = + GetResultWithIndexScan(column_ids, index_offset, values, txn); + // careful! the result tile could be null! + if (result_tiles == nullptr || result_tiles->size() == 0) { + LOG_INFO("no sequence on database %d and %s", database_oid, + sequence_name.c_str()); + return INVALID_OID; + } + + PELOTON_ASSERT(result_tiles->size() == 1); + return (*result_tiles)[0]->GetValue(0, 0).GetAs(); +} + +} // namespace catalog +} // namespace peloton diff --git a/src/catalog/system_catalogs.cpp b/src/catalog/system_catalogs.cpp index a2cbec24e60..dacc35f86ad 100644 --- a/src/catalog/system_catalogs.cpp +++ b/src/catalog/system_catalogs.cpp @@ -31,6 +31,7 @@ SystemCatalogs::SystemCatalogs(storage::Database *database, type::AbstractPool *pool, concurrency::TransactionContext *txn) : pg_trigger_(nullptr), + pg_sequence_(nullptr), pg_table_metrics_(nullptr), pg_index_metrics_(nullptr), pg_query_metrics_(nullptr) { @@ -74,6 +75,7 @@ SystemCatalogs::~SystemCatalogs() { delete pg_attribute_; delete pg_namespace_; if (pg_trigger_) delete pg_trigger_; + if (pg_sequence_) delete pg_sequence_; // if (pg_proc) delete pg_proc; if (pg_table_metrics_) delete pg_table_metrics_; if (pg_index_metrics_) delete pg_index_metrics_; @@ -92,6 +94,10 @@ void SystemCatalogs::Bootstrap(const std::string &database_name, pg_trigger_ = new TriggerCatalog(database_name, txn); } + if (!pg_sequence_) { + pg_sequence_ = new SequenceCatalog(database_name, txn); + } + // if (!pg_proc) { // pg_proc = new ProcCatalog(database_name, txn); // } diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index 8b8c85e4d76..cf93bbf9647 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -514,7 +514,7 @@ bool TableCatalog::DeleteTable(oid_t table_oid, // evict from cache auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, - table_oid); + table_oid); if (table_object) { auto database_object = DatabaseCatalog::GetInstance()->GetDatabaseObject(database_oid, txn); @@ -536,7 +536,7 @@ std::shared_ptr TableCatalog::GetTableObject( } // try get from cache auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, - table_oid); + table_oid); if (table_object) return table_object; // cache miss, get from pg_table @@ -582,7 +582,7 @@ std::shared_ptr TableCatalog::GetTableObject( throw CatalogException("Transaction is invalid!"); } // try get from cache - auto database_object = txn->catalog_cache.GetDatabaseObject(database_oid); + auto database_object = txn->GetCatalogCache()->GetDatabaseObject(database_oid); if (database_object) { auto table_object = database_object->GetTableObject(table_name, schema_name, true); @@ -677,7 +677,7 @@ bool TableCatalog::UpdateVersionId(oid_t update_val, oid_t table_oid, // get table object, then evict table object auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, - table_oid); + table_oid); if (table_object) { auto database_object = DatabaseCatalog::GetInstance()->GetDatabaseObject(database_oid, txn); diff --git a/src/codegen/proxy/sequence_functions_proxy.cpp b/src/codegen/proxy/sequence_functions_proxy.cpp new file mode 100644 index 00000000000..79694a33773 --- /dev/null +++ b/src/codegen/proxy/sequence_functions_proxy.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_functions_proxy.cpp +// +// Identification: src/codegen/proxy/sequence_functions_proxy.cpp +// +// Copyright (c) 2015-2017, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include "codegen/proxy/sequence_functions_proxy.h" + +#include "codegen/proxy/executor_context_proxy.h" + +namespace peloton { +namespace codegen { + +DEFINE_METHOD(peloton::function, SequenceFunctions, Nextval); +DEFINE_METHOD(peloton::function, SequenceFunctions, Currval); + +} // namespace codegen +} // namespace peloton diff --git a/src/codegen/type/bigint_type.cpp b/src/codegen/type/bigint_type.cpp index 45b43b3ad46..ef53d426fec 100644 --- a/src/codegen/type/bigint_type.cpp +++ b/src/codegen/type/bigint_type.cpp @@ -15,10 +15,12 @@ #include "codegen/lang/if.h" #include "codegen/value.h" #include "codegen/proxy/numeric_functions_proxy.h" +#include "codegen/proxy/sequence_functions_proxy.h" #include "codegen/proxy/values_runtime_proxy.h" #include "codegen/type/boolean_type.h" #include "codegen/type/decimal_type.h" #include "codegen/type/integer_type.h" +#include "codegen/type/varchar_type.h" #include "common/exception.h" #include "type/limits.h" #include "util/string_util.h" @@ -503,6 +505,46 @@ struct Modulo : public TypeSystem::BinaryOperatorHandleNull { } }; +// Nextval +struct Nextval : public TypeSystem::UnaryOperatorHandleNull { + bool SupportsType(const Type &type) const override { + return type.GetSqlType() == Varchar::Instance(); + } + + Type ResultType(UNUSED_ATTRIBUTE const Type &val_type) const override { + return BigInt::Instance(); + } + Value Impl(CodeGen &codegen, const Value &val, + const TypeSystem::InvocationContext &ctx) const override { + llvm::Value *executor_ctx = ctx.executor_context; + llvm::Value *raw_ret = + codegen.Call(SequenceFunctionsProxy::Nextval, + {executor_ctx, val.GetValue()}); + return Value{BigInt::Instance(), raw_ret}; + } +}; + +// Currval +struct Currval : public TypeSystem::UnaryOperatorHandleNull { + bool SupportsType(const Type &type) const override { + return type.GetSqlType() == Varchar::Instance(); + } + + Type ResultType(UNUSED_ATTRIBUTE const Type &val_type) const override { + return BigInt::Instance(); + } + + Value Impl(CodeGen &codegen, const Value &val, + const TypeSystem::InvocationContext &ctx) const override { + llvm::Value *executor_ctx = ctx.executor_context; + llvm::Value *raw_ret = + codegen.Call(SequenceFunctionsProxy::Currval, + {executor_ctx, val.GetValue()}); + return Value{BigInt::Instance(), raw_ret}; + } +}; + + //////////////////////////////////////////////////////////////////////////////// /// /// Function tables @@ -535,12 +577,16 @@ Abs kAbsOp; Ceil kCeilOp; Floor kFloorOp; Sqrt kSqrt; +Nextval kNextval; +Currval kCurrval; std::vector kUnaryOperatorTable = { {OperatorId::Negation, kNegOp}, {OperatorId::Abs, kAbsOp}, {OperatorId::Ceil, kCeilOp}, {OperatorId::Floor, kFloorOp}, - {OperatorId::Sqrt, kSqrt}}; + {OperatorId::Sqrt, kSqrt}, + {OperatorId::Nextval, kNextval}, + {OperatorId::Currval, kCurrval}}; // Binary operations Add kAddOp; diff --git a/src/common/internal_types.cpp b/src/common/internal_types.cpp index 855f7ef2d9b..d10e816b4a9 100644 --- a/src/common/internal_types.cpp +++ b/src/common/internal_types.cpp @@ -332,6 +332,9 @@ std::string CreateTypeToString(CreateType type) { case CreateType::SCHEMA: { return "SCHEMA"; } + case CreateType::SEQUENCE: { + return "SEQUENCE"; + } default: { throw ConversionException( StringUtil::Format("No string conversion for CreateType value '%d'", @@ -357,6 +360,8 @@ CreateType StringToCreateType(const std::string &str) { return CreateType::TRIGGER; } else if (upper_str == "SCHEMA") { return CreateType::SCHEMA; + } else if (upper_str == "SEQUENCE") { + return CreateType::SEQUENCE; } else { throw ConversionException(StringUtil::Format( "No CreateType conversion from string '%s'", upper_str.c_str())); @@ -391,6 +396,9 @@ std::string DropTypeToString(DropType type) { case DropType::SCHEMA: { return "SCHEMA"; } + case DropType::SEQUENCE: { + return "SEQUENCE"; + } default: { throw ConversionException( StringUtil::Format("No string conversion for DropType value '%d'", @@ -416,6 +424,8 @@ DropType StringToDropType(const std::string &str) { return DropType::TRIGGER; } else if (upper_str == "SCHEMA") { return DropType::SCHEMA; + } else if (upper_str == "SEQUENCE") { + return DropType::SEQUENCE; } else { throw ConversionException(StringUtil::Format( "No DropType conversion from string '%s'", upper_str.c_str())); @@ -557,6 +567,8 @@ std::string QueryTypeToString(QueryType query_type) { return "CREATE TRIGGER"; case QueryType::QUERY_CREATE_SCHEMA: return "CREATE SCHEMA"; + case QueryType::QUERY_CREATE_SEQUENCE: + return "CREATE SEQUENCE"; case QueryType::QUERY_CREATE_VIEW: return "CREATE VIEW"; case QueryType::QUERY_DROP: @@ -618,6 +630,7 @@ QueryType StringToQueryType(const std::string &str) { {"CREATE TRIGGER", QueryType::QUERY_CREATE_TRIGGER}, {"CREATE SCHEMA", QueryType::QUERY_CREATE_SCHEMA}, {"CREATE VIEW", QueryType::QUERY_CREATE_VIEW}, + {"CREATE SEQUENCE", QueryType::QUERY_CREATE_SEQUENCE}, {"OTHER", QueryType::QUERY_OTHER}, }; std::unordered_map::iterator it = @@ -688,6 +701,9 @@ QueryType StatementTypeToQueryType(StatementType stmt_type, case parser::CreateStatement::CreateType::kView: query_type = QueryType::QUERY_CREATE_VIEW; break; + case parser::CreateStatement::CreateType::kSequence: + query_type = QueryType::QUERY_CREATE_SEQUENCE; + break; } break; } diff --git a/src/concurrency/transaction_context.cpp b/src/concurrency/transaction_context.cpp index 498cc927e60..50b0685d369 100644 --- a/src/concurrency/transaction_context.cpp +++ b/src/concurrency/transaction_context.cpp @@ -83,6 +83,11 @@ void TransactionContext::Init(const size_t thread_id, gc_set_ = std::make_shared(); gc_object_set_ = std::make_shared(); + // TODO: I think that we need to delete this object when + // we delete the TransactionContext. It probably shouldn't + // be a shared_ptr since the TransactionContext owns it + catalog_cache.reset(new catalog::CatalogCache()); + on_commit_triggers_.reset(); } diff --git a/src/executor/create_executor.cpp b/src/executor/create_executor.cpp index 83e85c92c48..5f9ceb0471f 100644 --- a/src/executor/create_executor.cpp +++ b/src/executor/create_executor.cpp @@ -15,6 +15,10 @@ #include "catalog/catalog.h" #include "catalog/foreign_key.h" #include "catalog/system_catalogs.h" +#include "catalog/sequence_catalog.h" +#include "catalog/trigger_catalog.h" +#include "catalog/database_catalog.h" +#include "catalog/table_catalog.h" #include "concurrency/transaction_context.h" #include "executor/executor_context.h" #include "planner/create_plan.h" @@ -74,6 +78,12 @@ bool CreateExecutor::DExecute() { break; } + // if query was for creating sequence + case CreateType::SEQUENCE: { + result = CreateSequence(node); + break; + } + default: { std::string create_type = CreateTypeToString(node.GetCreateType()); LOG_ERROR("Not supported create type %s", create_type.c_str()); @@ -281,5 +291,36 @@ bool CreateExecutor::CreateTrigger(const planner::CreatePlan &node) { return (true); } +bool CreateExecutor::CreateSequence(const planner::CreatePlan &node) { + auto txn = context_->GetTransaction(); + std::string database_name = node.GetDatabaseName(); + std::string sequence_name = node.GetSequenceName(); + + auto database_object = catalog::Catalog::GetInstance()->GetDatabaseObject( + database_name, txn); + + catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_object->GetDatabaseOid()) + ->GetSequenceCatalog() + ->InsertSequence( + database_object->GetDatabaseOid(), sequence_name, + node.GetSequenceIncrement(), node.GetSequenceMaxValue(), + node.GetSequenceMinValue(), node.GetSequenceStart(), + node.GetSequenceCycle(), pool_.get(), txn); + + if (txn->GetResult() == ResultType::SUCCESS) { + LOG_DEBUG("Creating sequence succeeded!"); + } else if (txn->GetResult() == ResultType::FAILURE) { + LOG_DEBUG("Creating sequence failed!"); + } else { + LOG_DEBUG("Result is: %s", + ResultTypeToString(txn->GetResult()).c_str()); + } + + // Notice this action will always return true, since any exception + // will be handled in CreateSequence function in SequenceCatalog. + return (true); +} + } // namespace executor } // namespace peloton diff --git a/src/executor/drop_executor.cpp b/src/executor/drop_executor.cpp index 77030acbe21..d306ee8e464 100644 --- a/src/executor/drop_executor.cpp +++ b/src/executor/drop_executor.cpp @@ -65,6 +65,10 @@ bool DropExecutor::DExecute() { result = DropIndex(node, current_txn); break; } + case DropType::SEQUENCE:{ + result = DropSequence(node, current_txn); + break; + } default: { throw NotImplementedException( StringUtil::Format("Drop type %d not supported yet.\n", dropType)); @@ -215,6 +219,35 @@ bool DropExecutor::DropTrigger(const planner::DropPlan &node, return false; } +bool DropExecutor::DropSequence(const planner::DropPlan &node, + concurrency::TransactionContext *txn) { + std::string database_name = node.GetDatabaseName(); + std::string sequence_name = node.GetSequenceName(); + auto database_object = catalog::Catalog::GetInstance()->GetDatabaseObject( + database_name, txn); + + // drop sequence + ResultType result = + catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_object->GetDatabaseOid()) + ->GetSequenceCatalog() + ->DropSequence(database_name, sequence_name, txn); + txn->SetResult(result); + if (txn->GetResult() == ResultType::SUCCESS) { + LOG_DEBUG("Dropping sequence succeeded!"); + } else if (txn->GetResult() == ResultType::FAILURE && node.IsMissing()) { + txn->SetResult(ResultType::SUCCESS); + LOG_TRACE("Dropping Sequence Succeeded!"); + } else if (txn->GetResult() == ResultType::FAILURE && !node.IsMissing()) { + LOG_TRACE("Dropping Sequence Failed!"); + } else { + LOG_TRACE("Result is: %s", ResultTypeToString(txn->GetResult()).c_str()); + } + return false; +} + + + bool DropExecutor::DropIndex(const planner::DropPlan &node, concurrency::TransactionContext *txn) { std::string index_name = node.GetIndexName(); diff --git a/src/expression/function_expression.cpp b/src/expression/function_expression.cpp index 9f74f30e475..ab0ba3aac3b 100644 --- a/src/expression/function_expression.cpp +++ b/src/expression/function_expression.cpp @@ -12,6 +12,8 @@ #include "expression/function_expression.h" +#include "type/value_factory.h" + namespace peloton { namespace expression { @@ -42,13 +44,17 @@ expression::FunctionExpression::FunctionExpression( type::Value FunctionExpression::Evaluate( const AbstractTuple *tuple1, const AbstractTuple *tuple2, - UNUSED_ATTRIBUTE executor::ExecutorContext *context) const { + executor::ExecutorContext *context) const { std::vector child_values; PELOTON_ASSERT(func_.impl != nullptr); for (auto &child : children_) { child_values.push_back(child->Evaluate(tuple1, tuple2, context)); } + if (func_name_ == "nextval" || func_name_ == "currval") { + uint64_t ctx = (uint64_t)context; + child_values.push_back(type::ValueFactory::GetBigIntValue(ctx)); + } type::Value ret = func_.impl(child_values); diff --git a/src/function/sequence_functions.cpp b/src/function/sequence_functions.cpp new file mode 100644 index 00000000000..44962f9a088 --- /dev/null +++ b/src/function/sequence_functions.cpp @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_functions.cpp +// +// Identification: src/function/sequence_functions.cpp +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include "function/sequence_functions.h" + +#include "common/macros.h" +#include "executor/executor_context.h" +#include "catalog/catalog.h" +#include "catalog/database_catalog.h" +#include "catalog/sequence_catalog.h" +#include "concurrency/transaction_context.h" +#include "concurrency/transaction_manager_factory.h" +#include "type/value_factory.h" + +namespace peloton { +namespace function { + +/* + * @brief The actual implementation to get the incremented value for the specified sequence + * @param sequence name + * @param executor context + * @return the next value for the sequence + * @exception the sequence does not exist + */ +uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, + const char *sequence_name) { + PELOTON_ASSERT(sequence_name != nullptr); + concurrency::TransactionContext* txn = ctx.GetTransaction(); + + // HACK: Assume that there is only one database in our cache + auto all_databases = txn->GetCatalogCache()->GetAllDatabaseObjects(); + PELOTON_ASSERT(all_databases.empty() == false); + auto database_catalog = all_databases[0]; + LOG_DEBUG("Get database oid: %u", database_catalog->GetDatabaseOid()); + + // initialize a new transaction for incrementing sequence value + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto mini_txn = txn_manager.BeginTransaction(); + + // evict the old cached copy of sequence + txn->GetCatalogCache()->EvictSequenceObject(sequence_name, + database_catalog->GetDatabaseOid()); + auto sequence_object = + catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) + ->GetSequenceCatalog() + ->GetSequence(database_catalog->GetDatabaseOid(), + sequence_name, mini_txn); + + if (sequence_object != nullptr) { + uint32_t val = sequence_object->GetNextVal(); + int64_t curr_val = sequence_object->GetCurrVal(); + // insert the new copy of sequence into cache for future currval + txn->GetCatalogCache()->InsertSequenceObject(sequence_object); + + auto ret = txn_manager.CommitTransaction(mini_txn); + if (ret != ResultType::SUCCESS) { + txn_manager.AbortTransaction(mini_txn); + return Nextval(ctx, sequence_name); + } + + catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) + ->GetSequenceCatalog() + ->InsertCurrValCache("FIXME_SCHEMA", + sequence_name, curr_val); + return val; + } else { + throw SequenceException( + StringUtil::Format("Sequence \"%s\" does not exist", sequence_name)); + } +} + +/* + * @brief The actual implementation to get the current value for the specified sequence + * @param sequence name + * @param executor context + * @return the current value of a sequence + * @exception either the sequence does not exist, or 'call nextval before currval' + */ +uint32_t SequenceFunctions::Currval(executor::ExecutorContext &ctx, + const char *sequence_name) { + PELOTON_ASSERT(sequence_name != nullptr); + concurrency::TransactionContext* txn = ctx.GetTransaction(); + // get the database oid for this transaction + // HACK: Assume that there is only one database in our cache + auto all_databases = txn->GetCatalogCache()->GetAllDatabaseObjects(); + PELOTON_ASSERT(all_databases.empty() == false); + auto database_catalog = all_databases[0]; + + // get the sequence copy from cache + auto sequence_catalog = catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) + ->GetSequenceCatalog(); + + if(sequence_catalog->CheckCachedCurrValExistence( + "FIXME_SCHEMA", std::string(sequence_name))) { + return sequence_catalog->GetCachedCurrVal( + "FIXME_SCHEMA", std::string(sequence_name)); + } else { + // get sequence from catalog + auto sequence_object = sequence_catalog + ->GetSequence(database_catalog->GetDatabaseOid(), sequence_name, txn); + if (sequence_object != nullptr) { + throw SequenceException( + StringUtil::Format("currval for sequence \"%s\" is undefined for this session", + sequence_name)); + } else { + // sequence does not exist + throw SequenceException( + StringUtil::Format("Sequence \"%s\" does not exist", sequence_name)); + } + } +} + +/* + * @brief The wrapper function to get the incremented value for the specified sequence + * @param sequence name + * @param executor context + * @return the result of executing NextVal + */ +type::Value SequenceFunctions::_Nextval(const std::vector &args) { + executor::ExecutorContext* ctx = (executor::ExecutorContext*)args[1].GetAs(); + uint32_t ret = SequenceFunctions::Nextval(*ctx, args[0].GetAs()); + return type::ValueFactory::GetIntegerValue(ret); +} + +/* + * @brief The wrapper function to get the current value for the specified sequence + * @param sequence name + * @param executor context + * @return the result of executing CurrVal + */ +type::Value SequenceFunctions::_Currval(const std::vector &args) { + executor::ExecutorContext* ctx = (executor::ExecutorContext*)args[1].GetAs(); + uint32_t ret = SequenceFunctions::Currval(*ctx, args[0].GetAs()); + return type::ValueFactory::GetIntegerValue(ret); +} + +} // namespace function +} // namespace peloton diff --git a/src/include/catalog/catalog_cache.h b/src/include/catalog/catalog_cache.h index 45fa1417b01..6c39ea54cca 100644 --- a/src/include/catalog/catalog_cache.h +++ b/src/include/catalog/catalog_cache.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include #include "common/internal_types.h" @@ -23,14 +24,18 @@ namespace planner { class PlanUtil; } // namespace planner +namespace function { +class SequenceFunctions; +} // namespace function + namespace catalog { class DatabaseCatalogObject; +class SequenceCatalogObject; class TableCatalogObject; class IndexCatalogObject; class CatalogCache { - friend class Transaction; friend class DatabaseCatalog; friend class TableCatalog; friend class IndexCatalog; @@ -38,6 +43,8 @@ class CatalogCache { friend class TableCatalogObject; friend class IndexCatalogObject; friend class planner::PlanUtil; + friend class SequenceCatalogObject; + friend class function::SequenceFunctions; public: CatalogCache() {} @@ -49,13 +56,17 @@ class CatalogCache { std::shared_ptr GetDatabaseObject( const std::string &name); - std::shared_ptr GetCachedTableObject(oid_t database_oid, - oid_t table_oid); - std::shared_ptr GetCachedIndexObject(oid_t database_oid, - oid_t index_oid); + /** + * @brief Retrieve a vector of all the DatabaseObjects cached + * @return + */ + std::vector> GetAllDatabaseObjects(); + + std::shared_ptr GetCachedTableObject(oid_t database_oid, oid_t table_oid); + std::shared_ptr GetCachedIndexObject(oid_t database_oid, oid_t index_oid); std::shared_ptr GetCachedIndexObject( - const std::string &database_name, const std::string &index_name, - const std::string &schema_name); + const std::string &database_name, const std::string &index_name, + const std::string &schema_name); // database catalog cache interface bool InsertDatabaseObject( @@ -63,11 +74,25 @@ class CatalogCache { bool EvictDatabaseObject(oid_t database_oid); bool EvictDatabaseObject(const std::string &database_name); + // sequence catalog cache interface + bool InsertSequenceObject( + std::shared_ptr sequence_object); + bool EvictSequenceObject(const std::string &sequence_name, + oid_t database_oid); + std::shared_ptr GetSequenceObject( + const std::string &sequence_name, oid_t database_oid); + std::size_t GetHashKey(std::string sequence_name, oid_t database_oid); + // cache for database catalog object std::unordered_map> database_objects_cache; std::unordered_map> database_name_cache; + + // cache for sequence catalog object + std::unordered_map> + sequence_objects_cache; + }; } // namespace catalog diff --git a/src/include/catalog/catalog_defaults.h b/src/include/catalog/catalog_defaults.h index d8afd1a16d6..6cf00d14843 100644 --- a/src/include/catalog/catalog_defaults.h +++ b/src/include/catalog/catalog_defaults.h @@ -33,11 +33,12 @@ namespace catalog { #define INDEX_CATALOG_NAME "pg_index" #define COLUMN_CATALOG_NAME "pg_attribute" #define LAYOUT_CATALOG_NAME "pg_layout" +#define SEQUENCE_CATALOG_NAME "pg_sequence" // Local oids from START_OID = 0 to START_OID + OID_OFFSET are reserved #define OID_OFFSET 100 #define OID_FOR_USER_OFFSET 10000 -#define CATALOG_TABLES_COUNT 9 +#define CATALOG_TABLES_COUNT 10 // Oid mask for each type #define DATABASE_OID_MASK (static_cast(catalog::CatalogType::DATABASE)) @@ -47,6 +48,7 @@ namespace catalog { #define TRIGGER_OID_MASK (static_cast(catalog::CatalogType::TRIGGER)) #define LANGUAGE_OID_MASK (static_cast(catalog::CatalogType::LANGUAGE)) #define PROC_OID_MASK (static_cast(catalog::CatalogType::PROC)) +#define SEQUENCE_OID_MASK (static_cast(catalog::CatalogType::SEQUENCE)) // Reserved peloton database oid #define CATALOG_DATABASE_OID (0 | DATABASE_OID_MASK) @@ -110,7 +112,7 @@ enum class CatalogType : uint32_t { TRIGGER = 6 << CATALOG_TYPE_OFFSET, LANGUAGE = 7 << CATALOG_TYPE_OFFSET, PROC = 8 << CATALOG_TYPE_OFFSET, - // To be added + SEQUENCE = 9 << CATALOG_TYPE_OFFSET, }; } // namespace catalog diff --git a/src/include/catalog/sequence_catalog.h b/src/include/catalog/sequence_catalog.h new file mode 100644 index 00000000000..e75ffb198b0 --- /dev/null +++ b/src/include/catalog/sequence_catalog.h @@ -0,0 +1,225 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_catalog.h +// +// Identification: src/include/catalog/sequence_catalog.h +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// pg_trigger +// +// Schema: (column offset: column_name) +// 0: oid (pkey) +// 1: sqdboid : database_oid +// 2: sqname : sequence_name +// 3: sqinc : seq_increment +// 4: sqmax : seq_max +// 5: sqmin : seq_min +// 6: sqstart : seq_start +// 7: sqcycle : seq_cycle +// 7: sqval : seq_value +// +// Indexes: (index offset: indexed columns) +// 0: oid (primary key) +// 1: (sqdboid, sqname) (secondary key 0) +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include +#include +#include +#include + +#include "catalog/abstract_catalog.h" +#include "catalog/catalog_defaults.h" +#include "catalog/system_catalogs.h" + +namespace peloton { + +namespace concurrency { +class TransactionContext; +} + +namespace catalog { + +class SequenceCatalogObject { + public: + SequenceCatalogObject(oid_t seqoid, oid_t dboid, const std::string &name, + const int64_t seqstart, const int64_t seqincrement, + const int64_t seqmax, const int64_t seqmin, + const bool seqcycle, const int64_t seqval, + concurrency::TransactionContext *txn) + : seq_oid(seqoid), + db_oid(dboid), + seq_name(name), + seq_start(seqstart), + seq_increment(seqincrement), + seq_max(seqmax), + seq_min(seqmin), + seq_cycle(seqcycle), + txn_(txn), + seq_curr_val(seqval){}; + + oid_t seq_oid; + oid_t db_oid; + std::string seq_name; + int64_t seq_start; // Start value of the sequence + int64_t seq_increment; // Increment value of the sequence + int64_t seq_max; // Maximum value of the sequence + int64_t seq_min; // Minimum value of the sequence + int64_t seq_cache; // Cache size of the sequence + bool seq_cycle; // Whether the sequence cycles + concurrency::TransactionContext *txn_; + + int64_t seq_prev_val; + + int64_t GetNextVal(); + + int64_t GetCurrVal() { + return seq_prev_val; + }; + + void SetCurrVal(int64_t curr_val) { + seq_curr_val = curr_val; + }; // only visible for test! + void SetCycle(bool cycle) { seq_cycle = cycle; }; + + private: + int64_t seq_curr_val; +}; + +class SequenceCatalog : public AbstractCatalog { + public: + SequenceCatalog(const std::string &database_name, + concurrency::TransactionContext *txn); + ~SequenceCatalog(); + + //===--------------------------------------------------------------------===// + // write Related API + //===--------------------------------------------------------------------===// + bool InsertSequence(oid_t database_oid, std::string sequence_name, + int64_t seq_increment, int64_t seq_max, int64_t seq_min, + int64_t seq_start, bool seq_cycle, + type::AbstractPool *pool, + concurrency::TransactionContext *txn); + + ResultType DropSequence(const std::string &database_name, + const std::string &sequence_name, + concurrency::TransactionContext *txn); + + bool DeleteSequenceByName(const std::string &sequence_name, + oid_t database_oid, + concurrency::TransactionContext *txn); + + std::shared_ptr GetSequence( + oid_t database_oid, const std::string &sequence_name, + concurrency::TransactionContext *txn); + + oid_t GetSequenceOid(std::string sequence_name, oid_t database_oid, + concurrency::TransactionContext *txn); + + bool UpdateNextVal(oid_t sequence_oid, int64_t nextval, + concurrency::TransactionContext *txn); + + enum ColumnId { + SEQUENCE_OID = 0, + DATABSE_OID = 1, + SEQUENCE_NAME = 2, + SEQUENCE_INC = 3, + SEQUENCE_MAX = 4, + SEQUENCE_MIN = 5, + SEQUENCE_START = 6, + SEQUENCE_CYCLE = 7, + SEQUENCE_VALUE = 8 + }; + + enum IndexId { + PRIMARY_KEY = 0, + DBOID_SEQNAME_KEY = 1 + }; + + void InsertCurrValCache(std::string session_namespace_, std::string sequence_name, int64_t currval){ + std::tuple key(session_namespace_, sequence_name); + size_t hash_key = key_hash(key); + sequence_currval_cache[hash_key] = currval; + namespace_hash_lists[session_namespace_].push_back(hash_key); + sequence_name_hash_lists[sequence_name].push_back(hash_key); + } + + void EvictNamespaceCurrValCache(std::string session_namespace_){ + std::vector hash_keys = namespace_hash_lists[session_namespace_]; + for (size_t hash_key : hash_keys){ + sequence_currval_cache.erase(hash_key); + } + namespace_hash_lists.erase(session_namespace_); + } + + void EvictSequenceNameCurrValCache(std::string sequence_name){ + std::vector hash_keys = sequence_name_hash_lists[sequence_name]; + for (size_t hash_key : hash_keys){ + sequence_currval_cache.erase(hash_key); + } + sequence_name_hash_lists.erase(sequence_name); + } + + bool CheckCachedCurrValExistence(std::string session_namespace_, std::string sequence_name) { + std::tuple key(session_namespace_, sequence_name); + size_t hash_key = key_hash(key); + + if (sequence_currval_cache.find(hash_key) != sequence_currval_cache.end()) + return true; + + return false; + } + + int64_t GetCachedCurrVal(std::string session_namespace_, std::string sequence_name){ + std::tuple key(session_namespace_, sequence_name); + size_t hash_key = key_hash(key); + + return sequence_currval_cache.find(hash_key)->second; + } + + private: + oid_t GetNextOid() { return oid_++ | SEQUENCE_OID_MASK; } + + std::unordered_map sequence_currval_cache; + std::unordered_map> namespace_hash_lists; + std::unordered_map> sequence_name_hash_lists; + boost::hash> key_hash; + + void ValidateSequenceArguments(int64_t seq_increment, int64_t seq_max, + int64_t seq_min, int64_t seq_start) { + if (seq_min > seq_max) { + throw SequenceException( + StringUtil::Format( + "MINVALUE (%ld) must be no greater than MAXVALUE (%ld)", seq_min, seq_max)); + } + + if (seq_increment == 0) { + throw SequenceException( + StringUtil::Format("INCREMENT must not be zero")); + } + + if (seq_increment > 0 && seq_start < seq_min) { + throw SequenceException( + StringUtil::Format( + "START value (%ld) cannot be less than MINVALUE (%ld)", seq_start, seq_min)); + } + + if (seq_increment < 0 && seq_start > seq_max) { + throw SequenceException( + StringUtil::Format( + "START value (%ld) cannot be greater than MAXVALUE (%ld)", seq_start, seq_max)); + } + }; +}; + +} // namespace catalog +} // namespace peloton diff --git a/src/include/catalog/system_catalogs.h b/src/include/catalog/system_catalogs.h index 9792d180f9d..0d0fbda2d04 100644 --- a/src/include/catalog/system_catalogs.h +++ b/src/include/catalog/system_catalogs.h @@ -21,6 +21,7 @@ #include "catalog/table_catalog.h" #include "catalog/table_metrics_catalog.h" #include "catalog/trigger_catalog.h" +#include "catalog/sequence_catalog.h" namespace peloton { @@ -35,6 +36,7 @@ class TableCatalog; class IndexCatalog; class ColumnCatalog; class LayoutCatalog; +class SequenceCatalog; class SystemCatalogs { public: @@ -94,6 +96,13 @@ class SystemCatalogs { return pg_trigger_; } + SequenceCatalog *GetSequenceCatalog() { + if (!pg_sequence_) { + throw CatalogException("Sequence catalog catalog has not been initialized"); + } + return pg_sequence_; + } + TableMetricsCatalog *GetTableMetricsCatalog() { if (!pg_table_metrics_) { throw CatalogException("Table metrics catalog has not been initialized"); @@ -123,6 +132,8 @@ class SystemCatalogs { LayoutCatalog *pg_layout_; TriggerCatalog *pg_trigger_; + SequenceCatalog *pg_sequence_; + // ProcCatalog *pg_proc; TableMetricsCatalog *pg_table_metrics_; IndexMetricsCatalog *pg_index_metrics_; diff --git a/src/include/codegen/proxy/sequence_functions_proxy.h b/src/include/codegen/proxy/sequence_functions_proxy.h new file mode 100644 index 00000000000..222b6cf4fe2 --- /dev/null +++ b/src/include/codegen/proxy/sequence_functions_proxy.h @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// string_functions_proxy.h +// +// Identification: src/include/codegen/proxy/string_functions_proxy.h +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "codegen/proxy/proxy.h" +#include "codegen/proxy/type_builder.h" +#include "function/sequence_functions.h" + +namespace peloton { +namespace codegen { + +PROXY(SequenceFunctions) { + DECLARE_METHOD(Nextval); + DECLARE_METHOD(Currval); +}; + +} // namespace codegen +} // namespace peloton diff --git a/src/include/common/exception.h b/src/include/common/exception.h index 7f25ec20e9f..3d2efef511f 100644 --- a/src/include/common/exception.h +++ b/src/include/common/exception.h @@ -60,7 +60,8 @@ enum class ExceptionType { BINDER = 24, // binder related NETWORK = 25, // network related OPTIMIZER = 26, // optimizer related - NULL_POINTER = 27 // nullptr exception + NULL_POINTER = 27, // nullptr exception + SEQUENCE = 28 // sequence related }; class Exception : public std::runtime_error { @@ -135,6 +136,8 @@ class Exception : public std::runtime_error { return "Optimizer"; case ExceptionType::NULL_POINTER: return "NullPointer"; + case ExceptionType::SEQUENCE: + return "Sequence"; default: return "Unknown"; } @@ -478,4 +481,12 @@ class NullPointerException : public Exception { : Exception(ExceptionType::NULL_POINTER, msg) {} }; +class SequenceException : public Exception { + SequenceException() = delete; + + public: + SequenceException(std::string msg) + : Exception(ExceptionType::SEQUENCE, msg) {} +}; + } // namespace peloton diff --git a/src/include/common/internal_types.h b/src/include/common/internal_types.h index 22598226407..e540d66bb89 100644 --- a/src/include/common/internal_types.h +++ b/src/include/common/internal_types.h @@ -617,6 +617,7 @@ enum class CreateType { CONSTRAINT = 4, // constraint create type TRIGGER = 5, // trigger create type SCHEMA = 6, // schema create type + SEQUENCE = 7 }; std::string CreateTypeToString(CreateType type); CreateType StringToCreateType(const std::string &str); @@ -633,7 +634,8 @@ enum class DropType { INDEX = 3, // index drop type CONSTRAINT = 4, // constraint drop type TRIGGER = 5, // trigger drop type - SCHEMA = 6, // trigger drop type + SCHEMA = 6, // schema drop type + SEQUENCE = 7, // sequence drop type }; std::string DropTypeToString(DropType type); DropType StringToDropType(const std::string &str); @@ -713,7 +715,9 @@ enum class QueryType { QUERY_CREATE_TRIGGER = 21, QUERY_CREATE_SCHEMA = 22, QUERY_CREATE_VIEW = 23, - QUERY_EXPLAIN = 24 + QUERY_EXPLAIN = 24, + QUERY_CREATE_SEQUENCE = 25, + QUERY_DROP_SEQUENCE = 26 }; std::string QueryTypeToString(QueryType query_type); QueryType StringToQueryType(std::string str); @@ -1102,6 +1106,8 @@ enum class OperatorId : uint32_t { DateTrunc, Like, Now, + Nextval, + Currval, // Add more operators here, before the last "Invalid" entry Invalid diff --git a/src/include/concurrency/transaction_context.h b/src/include/concurrency/transaction_context.h index 04419082825..4c333dcfcbb 100644 --- a/src/include/concurrency/transaction_context.h +++ b/src/include/concurrency/transaction_context.h @@ -69,6 +69,14 @@ class TransactionContext : public Printable { // Mutators and Accessors //===--------------------------------------------------------------------===// + /** + * @brief Get the CatalogCache for this txn + * @return the CatalogCache for this txn + */ + inline std::shared_ptr GetCatalogCache() const { + return (catalog_cache); + } + /** * @brief Gets the thread identifier. * @@ -282,14 +290,14 @@ class TransactionContext : public Printable { return isolation_level_; } - /** cache for table catalog objects */ - catalog::CatalogCache catalog_cache; - private: //===--------------------------------------------------------------------===// // Data members //===--------------------------------------------------------------------===// + /** cache for table catalog objects */ + std::shared_ptr catalog_cache; + /** transaction id */ txn_id_t txn_id_; diff --git a/src/include/executor/create_executor.h b/src/include/executor/create_executor.h index 19b29dd24aa..902e44bd6b4 100644 --- a/src/include/executor/create_executor.h +++ b/src/include/executor/create_executor.h @@ -54,6 +54,8 @@ class CreateExecutor : public AbstractExecutor { bool CreateTrigger(const planner::CreatePlan &node); + bool CreateSequence(const planner::CreatePlan &node); + private: ExecutorContext *context_; diff --git a/src/include/executor/drop_executor.h b/src/include/executor/drop_executor.h index 4454ebe2b5d..8e792083518 100644 --- a/src/include/executor/drop_executor.h +++ b/src/include/executor/drop_executor.h @@ -59,6 +59,9 @@ class DropExecutor : public AbstractExecutor { bool DropIndex(const planner::DropPlan &node, concurrency::TransactionContext *txn); + + bool DropSequence(const planner::DropPlan &node, + concurrency::TransactionContext *txn); private: ExecutorContext *context_; diff --git a/src/include/function/sequence_functions.h b/src/include/function/sequence_functions.h new file mode 100644 index 00000000000..a91faf5dffd --- /dev/null +++ b/src/include/function/sequence_functions.h @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_functions.h +// +// Identification: src/include/function/sequence_functions.h +// +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include "type/value.h" + +namespace peloton { + +namespace executor { +class ExecutorContext; +} // namespace executor + +namespace function { + +class SequenceFunctions { + public: + + // Nextval will return the next value of the given sequence + static uint32_t Nextval(executor::ExecutorContext &ctx, const char *sequence_name); + + // Currval will return the current value of the given sequence + static uint32_t Currval(executor::ExecutorContext &ctx, const char *sequence_name); + + // Wrapper function used for AddBuiltin Functions + static type::Value _Nextval(const std::vector &args); + static type::Value _Currval(const std::vector &args); +}; + +} // namespace function +} // namespace peloton diff --git a/src/include/parser/create_statement.h b/src/include/parser/create_statement.h index f83b24222ef..84b8fe9c352 100644 --- a/src/include/parser/create_statement.h +++ b/src/include/parser/create_statement.h @@ -215,7 +215,15 @@ struct ColumnDefinition { */ class CreateStatement : public TableRefStatement { public: - enum CreateType { kTable, kDatabase, kIndex, kTrigger, kSchema, kView }; + enum CreateType { + kTable, + kDatabase, + kIndex, + kTrigger, + kSchema, + kView, + kSequence + }; CreateStatement(CreateType type) : TableRefStatement(StatementType::CREATE), @@ -252,6 +260,14 @@ class CreateStatement : public TableRefStatement { std::unique_ptr trigger_when; int16_t trigger_type; // information about row, timing, events, access by // pg_trigger + + // attributes related to sequences + std::string sequence_name; + int64_t seq_start = 1; + int64_t seq_increment = 1; + int64_t seq_max_value = LONG_MAX; + int64_t seq_min_value = 1; + bool seq_cycle = false; }; } // namespace parser diff --git a/src/include/parser/drop_statement.h b/src/include/parser/drop_statement.h index 9612ed5fe7e..4bb693af3b0 100644 --- a/src/include/parser/drop_statement.h +++ b/src/include/parser/drop_statement.h @@ -31,7 +31,8 @@ class DropStatement : public TableRefStatement { kIndex, kView, kPreparedStatement, - kTrigger + kTrigger, + kSequence }; DropStatement(EntityType type) @@ -81,6 +82,13 @@ class DropStatement : public TableRefStatement { std::string GetTriggerTableName() { return GetTableName(); } + std::string &GetSequenceName() { return sequence_name_; } + + void SetSequenceName(std::string &sequence_name) { + sequence_name_ = sequence_name; + } + void SetSequenceName(char *sequence_name) { sequence_name_ = sequence_name; } + virtual ~DropStatement() {} virtual void Accept(SqlNodeVisitor *v) override { v->Visit(this); } @@ -105,6 +113,9 @@ class DropStatement : public TableRefStatement { // drop trigger std::string trigger_name_; + + // drop sequence + std::string sequence_name_; }; } // namespace parser diff --git a/src/include/parser/parsenodes.h b/src/include/parser/parsenodes.h index bf818ff6b86..606e7cbdd38 100644 --- a/src/include/parser/parsenodes.h +++ b/src/include/parser/parsenodes.h @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +#pragma once + #include #include "nodes.h" @@ -730,6 +732,16 @@ typedef struct CreateSchemaStmt bool if_not_exists; /* just do nothing if schema already exists? */ } CreateSchemaStmt; +typedef struct CreateSeqStmt +{ + NodeTag type; + RangeVar *sequence; /* the sequence to create */ + List *options; + Oid ownerId; /* ID of owner, or InvalidOid for default */ + bool for_identity; + bool if_not_exists; /* just do nothing if it already exists? */ +} CreateSeqStmt; + typedef enum RoleSpecType { ROLESPEC_CSTRING, /* role name is stored as a C string */ diff --git a/src/include/parser/postgresparser.h b/src/include/parser/postgresparser.h index 388623a138c..c9912fdceac 100644 --- a/src/include/parser/postgresparser.h +++ b/src/include/parser/postgresparser.h @@ -203,6 +203,8 @@ class PostgresParser { // transform helper for create view statements static parser::SQLStatement *CreateViewTransform(ViewStmt *root); + static parser::SQLStatement *CreateSequenceTransform(CreateSeqStmt *root); + // transform helper for column name (for insert statement) static std::vector *ColumnNameTransform(List *root); @@ -253,6 +255,9 @@ class PostgresParser { // transform helper for drop trigger statement static parser::DropStatement *DropTriggerTransform(DropStmt *root); + // transform helper for drop sequence statement + static parser::DropStatement *DropSequenceTransform(DropStmt *root); + // transform helper for drop schema statement static parser::DropStatement *DropSchemaTransform(DropStmt *root); @@ -289,6 +294,12 @@ class PostgresParser { // transform helper for subquery expressions static expression::AbstractExpression *SubqueryExprTransform(SubLink *node); + static void ParseSequenceParams(List *options, + parser::CreateStatement *result); + + static int64_t GetLongInDefElem(DefElem *defel) { + return (int64_t)((reinterpret_cast(defel->arg))->val.ival); + }; }; } // namespace parser diff --git a/src/include/planner/create_plan.h b/src/include/planner/create_plan.h index ecf6a0524fe..c8fe7e4e305 100644 --- a/src/include/planner/create_plan.h +++ b/src/include/planner/create_plan.h @@ -51,10 +51,10 @@ class CreatePlan : public AbstractPlan { public: CreatePlan() = delete; - // This construnctor is for Create Database Test used only + // This constructor is for Create Database Test used only explicit CreatePlan(std::string database_name, CreateType c_type); - // This construnctor is for copy() used only + // This constructor is for copy() used only explicit CreatePlan(std::string table_name, std::string schema_name, std::string database_name, std::unique_ptr schema, @@ -114,6 +114,14 @@ class CreatePlan : public AbstractPlan { int16_t GetTriggerType() const { return trigger_type; } + std::string GetSequenceName() const { return sequence_name; } + int64_t GetSequenceStart() const { return seq_start; }; + int64_t GetSequenceIncrement() const { return seq_increment; } + int64_t GetSequenceMaxValue() const { return seq_max_value; } + int64_t GetSequenceMinValue() const { return seq_min_value; } + int64_t GetSequenceCacheSize() const { return seq_cache; } + bool GetSequenceCycle() const { return seq_cycle; } + protected: // This is a helper method for extracting foreign key information // and storing it in an internal struct. @@ -159,6 +167,15 @@ class CreatePlan : public AbstractPlan { int16_t trigger_type; // information about row, timing, events, access by // pg_trigger + // information for sequences; + std::string sequence_name; + int64_t seq_start; + int64_t seq_increment; + int64_t seq_max_value; + int64_t seq_min_value; + int64_t seq_cache; // sequence cache size, not supported yet + bool seq_cycle; + private: DISALLOW_COPY_AND_MOVE(CreatePlan); }; diff --git a/src/include/planner/drop_plan.h b/src/include/planner/drop_plan.h index c5593680202..9ef92f73c93 100644 --- a/src/include/planner/drop_plan.h +++ b/src/include/planner/drop_plan.h @@ -57,6 +57,8 @@ class DropPlan : public AbstractPlan { std::string GetSchemaName() const { return schema_name; } std::string GetTriggerName() const { return trigger_name; } + + std::string GetSequenceName() const { return sequence_name; } std::string GetIndexName() const { return index_name; } @@ -77,6 +79,10 @@ class DropPlan : public AbstractPlan { std::string schema_name; std::string trigger_name; + + // sequence name + std::string sequence_name; + std::string index_name; bool missing; diff --git a/src/include/planner/plan_util.h b/src/include/planner/plan_util.h index ca73beb46ea..1d4dfe787fb 100644 --- a/src/include/planner/plan_util.h +++ b/src/include/planner/plan_util.h @@ -62,7 +62,7 @@ class PlanUtil { * @return set of affected index object ids */ static const std::set GetAffectedIndexes( - catalog::CatalogCache &catalog_cache, + std::shared_ptr catalog_cache, const parser::SQLStatement &sql_stmt); /** @@ -73,7 +73,7 @@ class PlanUtil { * @return vector of affected column ids with triplet format */ static const std::vector GetIndexableColumns( - catalog::CatalogCache &catalog_cache, + std::shared_ptr catalog_cache, std::unique_ptr sql_stmt_list, const std::string &db_name); diff --git a/src/network/postgres_protocol_handler.cpp b/src/network/postgres_protocol_handler.cpp index 644e8dfef16..5d8b85ef0f7 100644 --- a/src/network/postgres_protocol_handler.cpp +++ b/src/network/postgres_protocol_handler.cpp @@ -1218,6 +1218,7 @@ void PostgresProtocolHandler::CompleteCommand(const QueryType &query_type, case QueryType::QUERY_CREATE_DB: case QueryType::QUERY_CREATE_INDEX: case QueryType::QUERY_CREATE_TRIGGER: + case QueryType::QUERY_CREATE_SEQUENCE: case QueryType::QUERY_PREPARE: break; default: diff --git a/src/parser/create_statement.cpp b/src/parser/create_statement.cpp index 40be9a437fa..bfe014885b6 100644 --- a/src/parser/create_statement.cpp +++ b/src/parser/create_statement.cpp @@ -72,6 +72,12 @@ const std::string CreateStatement::GetInfo(int num_indent) const { << StringUtil::Format("View name: %s", view_name.c_str()); break; } + case CreateStatement::CreateType::kSequence: { + os << "Create type: Sequence" << std::endl; + os << StringUtil::Indent(num_indent + 1) + << StringUtil::Format("Sequence name: %s", sequence_name.c_str()); + break; + } } os << std::endl; diff --git a/src/parser/drop_statement.cpp b/src/parser/drop_statement.cpp index feb266f89f2..348ed48e8b5 100644 --- a/src/parser/drop_statement.cpp +++ b/src/parser/drop_statement.cpp @@ -66,6 +66,14 @@ const std::string DropStatement::GetInfo(int num_indent) const { << "Trigger name: " << trigger_name_; break; } + case kSequence: { + os << "DropType: Sequence\n"; + os << StringUtil::Indent(num_indent + 1) + << "Sequence database name: " << GetDatabaseName() << std::endl; + os << StringUtil::Indent(num_indent + 1) + << "Sequence name: " << sequence_name_; + break; + } } os << std::endl; os << StringUtil::Indent(num_indent + 1) diff --git a/src/parser/postgresparser.cpp b/src/parser/postgresparser.cpp index 069285fc1a4..53ae3f1cec9 100644 --- a/src/parser/postgresparser.cpp +++ b/src/parser/postgresparser.cpp @@ -1352,12 +1352,83 @@ parser::SQLStatement *PostgresParser::CreateViewTransform(ViewStmt *root) { return result; } +parser::SQLStatement *PostgresParser::CreateSequenceTransform( + CreateSeqStmt *root) { + parser::CreateStatement *result = + new parser::CreateStatement(CreateStatement::kSequence); + result->sequence_name = std::string(root->sequence->relname); + ParseSequenceParams(root->options, result); + return result; +} + +void PostgresParser::ParseSequenceParams(List *options, + parser::CreateStatement *result) { + DefElem *start_value = NULL; + DefElem *increment_by = NULL; + DefElem *max_value = NULL; + DefElem *min_value = NULL; + DefElem *is_cycled = NULL; + if (!options) return; + + ListCell *option; + for (option = options->head; option != NULL; option = lnext(option)) { + DefElem *defel = (DefElem *)lfirst(option); + + if (strcmp(defel->defname, "increment") == 0) { + if (increment_by) + throw ParserException( + "Redundant definition of increment in defining sequence"); + increment_by = defel; + result->seq_increment = GetLongInDefElem(increment_by); + } else if (strcmp(defel->defname, "start") == 0) { + if (start_value) + throw ParserException( + "Redundant definition of start in defining sequence"); + start_value = defel; + result->seq_start = GetLongInDefElem(start_value); + } else if (strcmp(defel->defname, "maxvalue") == 0) { + if (max_value) + throw ParserException( + "Redundant definition of max in defining sequence"); + max_value = defel; + result->seq_max_value = GetLongInDefElem(max_value); + } else if (strcmp(defel->defname, "minvalue") == 0) { + if (min_value) + throw ParserException( + "Redundant definition of min in defining sequence"); + min_value = defel; + result->seq_min_value = GetLongInDefElem(min_value); + } else if (strcmp(defel->defname, "cycle") == 0) { + if (is_cycled) + throw ParserException( + "Redundant definition of cycle in defining sequence"); + is_cycled = defel; + result->seq_cycle = (bool)GetLongInDefElem(is_cycled); + } + else + throw ParserException( + StringUtil::Format("option \"%s\" not recognized\n", defel->defname)); + } + + // manually set the start value for a sequence + if (!start_value) { + if(result->seq_increment < 0 && max_value){ + result->seq_start = result->seq_max_value; + } + else if (result->seq_increment > 0 && min_value){ + result->seq_start = result->seq_min_value; + } + } +} + parser::DropStatement *PostgresParser::DropTransform(DropStmt *root) { switch (root->removeType) { case ObjectType::OBJECT_TABLE: return DropTableTransform(root); case ObjectType::OBJECT_TRIGGER: return DropTriggerTransform(root); + case ObjectType::OBJECT_SEQUENCE: + return DropSequenceTransform(root); case ObjectType::OBJECT_INDEX: return DropIndexTransform(root); case ObjectType::OBJECT_SCHEMA: @@ -1431,6 +1502,16 @@ parser::DropStatement *PostgresParser::DropTriggerTransform(DropStmt *root) { return result; } +parser::DropStatement *PostgresParser::DropSequenceTransform(DropStmt *root) { + auto result = new DropStatement(DropStatement::EntityType::kSequence); + auto cell = root->objects->head; + auto list = reinterpret_cast(cell->data.ptr_value); + // first, set sequence name + result->SetSequenceName( + reinterpret_cast(list->tail->data.ptr_value)->val.str); + return result; +} + parser::DropStatement *PostgresParser::DropSchemaTransform(DropStmt *root) { auto result = new DropStatement(DropStatement::EntityType::kSchema); result->SetCascade(root->behavior == DropBehavior::DROP_CASCADE); @@ -1843,6 +1924,9 @@ parser::SQLStatement *PostgresParser::NodeTransform(Node *stmt) { result = CreateSchemaTransform(reinterpret_cast(stmt)); break; + case T_CreateSeqStmt: + result = CreateSequenceTransform(reinterpret_cast(stmt)); + break; case T_ViewStmt: result = CreateViewTransform(reinterpret_cast(stmt)); break; diff --git a/src/planner/create_plan.cpp b/src/planner/create_plan.cpp index 2a23a75abb4..83e6cc259ff 100644 --- a/src/planner/create_plan.cpp +++ b/src/planner/create_plan.cpp @@ -205,6 +205,18 @@ CreatePlan::CreatePlan(parser::CreateStatement *parse_tree) { break; } + case parser::CreateStatement::CreateType::kSequence: { + create_type = CreateType::SEQUENCE; + database_name = std::string(parse_tree->GetDatabaseName()); + + sequence_name = parse_tree->sequence_name; + seq_start = parse_tree->seq_start; + seq_increment = parse_tree->seq_increment; + seq_max_value = parse_tree->seq_max_value; + seq_min_value = parse_tree->seq_min_value; + seq_cycle = parse_tree->seq_cycle; + break; + } default: LOG_ERROR("UNKNOWN CREATE TYPE"); // TODO Should we handle this here? diff --git a/src/planner/drop_plan.cpp b/src/planner/drop_plan.cpp index 34240f85cad..21e92cfcc9a 100644 --- a/src/planner/drop_plan.cpp +++ b/src/planner/drop_plan.cpp @@ -64,6 +64,13 @@ DropPlan::DropPlan(parser::DropStatement *parse_tree) { drop_type = DropType::INDEX; break; } + case parser::DropStatement::EntityType::kSequence: { + database_name = parse_tree->GetDatabaseName(); + sequence_name = parse_tree->GetSequenceName(); + drop_type = DropType::SEQUENCE; + break; + } + default: { LOG_ERROR("Not supported Drop type"); } } } diff --git a/src/planner/plan_util.cpp b/src/planner/plan_util.cpp index cb013fb1531..da24207be63 100644 --- a/src/planner/plan_util.cpp +++ b/src/planner/plan_util.cpp @@ -34,7 +34,7 @@ namespace peloton { namespace planner { const std::set PlanUtil::GetAffectedIndexes( - catalog::CatalogCache &catalog_cache, + std::shared_ptr catalog_cache, const parser::SQLStatement &sql_stmt) { std::set index_oids; std::string db_name, table_name, schema_name; @@ -56,7 +56,7 @@ const std::set PlanUtil::GetAffectedIndexes( table_name = delete_stmt.GetTableName(); schema_name = delete_stmt.GetSchemaName(); } - auto indexes_map = catalog_cache.GetDatabaseObject(db_name) + auto indexes_map = catalog_cache->GetDatabaseObject(db_name) ->GetTableObject(table_name, schema_name) ->GetIndexObjects(); for (auto &index : indexes_map) { @@ -69,7 +69,7 @@ const std::set PlanUtil::GetAffectedIndexes( db_name = update_stmt.table->GetDatabaseName(); table_name = update_stmt.table->GetTableName(); schema_name = update_stmt.table->GetSchemaName(); - auto table_object = catalog_cache.GetDatabaseObject(db_name) + auto table_object = catalog_cache->GetDatabaseObject(db_name) ->GetTableObject(table_name, schema_name); auto &update_clauses = update_stmt.updates; @@ -105,7 +105,7 @@ const std::set PlanUtil::GetAffectedIndexes( } const std::vector PlanUtil::GetIndexableColumns( - catalog::CatalogCache &catalog_cache, + std::shared_ptr catalog_cache, std::unique_ptr sql_stmt_list, const std::string &db_name) { std::vector column_oids; @@ -132,7 +132,7 @@ const std::vector PlanUtil::GetIndexableColumns( try { auto plan = optimizer->BuildPelotonPlanTree(sql_stmt_list, txn); - auto db_object = catalog_cache.GetDatabaseObject(db_name); + auto db_object = catalog_cache->GetDatabaseObject(db_name); database_id = db_object->GetDatabaseOid(); // Perform a breadth first search on plan tree diff --git a/test/function/sequence_functions_test.cpp b/test/function/sequence_functions_test.cpp new file mode 100644 index 00000000000..1072c378e6c --- /dev/null +++ b/test/function/sequence_functions_test.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_functions_test.cpp +// +// Identification: test/function/sequence_functions_test.cpp +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +#include "catalog/catalog.h" +#include "catalog/sequence_catalog.h" +#include "storage/abstract_table.h" +#include "common/harness.h" +#include "common/exception.h" +#include "executor/executors.h" +#include "parser/postgresparser.h" +#include "planner/create_plan.h" +#include "executor/executor_context.h" +#include "function/sequence_functions.h" +#include "concurrency/transaction_manager_factory.h" + +using ::testing::NotNull; +using ::testing::Return; + +namespace peloton { +namespace test { + +class SequenceFunctionsTests : public PelotonTest { + + protected: + void CreateDatabaseHelper() { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + catalog::Catalog::GetInstance()->Bootstrap(); + catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn); + txn_manager.CommitTransaction(txn); + } + + void CreateSequenceHelper(std::string query, + concurrency::TransactionContext *txn) { + auto parser = parser::PostgresParser::GetInstance(); + + std::unique_ptr stmt_list( + parser.BuildParseTree(query).release()); + EXPECT_TRUE(stmt_list->is_valid); + EXPECT_EQ(StatementType::CREATE, stmt_list->GetStatement(0)->GetType()); + auto create_sequence_stmt = + static_cast(stmt_list->GetStatement(0)); + + create_sequence_stmt->TryBindDatabaseName(DEFAULT_DB_NAME); + // Create plans + planner::CreatePlan plan(create_sequence_stmt); + + // plan type + EXPECT_EQ(CreateType::SEQUENCE, plan.GetCreateType()); + + // Execute the create sequence + std::unique_ptr context( + new executor::ExecutorContext(txn, {})); + executor::CreateExecutor createSequenceExecutor(&plan, context.get()); + createSequenceExecutor.Init(); + createSequenceExecutor.Execute(); + } + +}; +TEST_F(SequenceFunctionsTests, BasicTest) { + CreateDatabaseHelper(); + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + // Create statement + std::string query = "CREATE SEQUENCE seq;"; + + CreateSequenceHelper(query, txn); + txn_manager.CommitTransaction(txn); +} + +TEST_F(SequenceFunctionsTests, FunctionsTest) { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + std::unique_ptr context( + new executor::ExecutorContext(txn, {})); + + // Expect exception + try { + function::SequenceFunctions::Currval(*(context.get()), "seq"); + EXPECT_EQ(0, 1); + } catch (const SequenceException &expected) { + ASSERT_STREQ("currval for sequence \"seq\" is undefined for this session", expected.what()); + } + + // Check nextval & currval functionality + auto res = function::SequenceFunctions::Nextval(*(context.get()), "seq"); + EXPECT_EQ(1, res); + + res = function::SequenceFunctions::Currval(*(context.get()), "seq"); + EXPECT_EQ(1, res); + + txn_manager.CommitTransaction(txn); +} +} // namespace test +} // namespace peloton diff --git a/test/parser/postgresparser_test.cpp b/test/parser/postgresparser_test.cpp index dee0d981491..8cd9f4960ca 100644 --- a/test/parser/postgresparser_test.cpp +++ b/test/parser/postgresparser_test.cpp @@ -1069,6 +1069,55 @@ TEST_F(PostgresParserTests, DropTriggerTest) { EXPECT_EQ("films", drop_trigger_stmt->GetTriggerTableName()); } +TEST_F(PostgresParserTests, CreateSequenceTest) { + auto parser = parser::PostgresParser::GetInstance(); + + // missing AS, CACHE and OWNED BY. + std::string query = + "CREATE SEQUENCE seq " + "INCREMENT BY 2 " + "MINVALUE 10 " + "MAXVALUE 50 " + "CYCLE " + "START 10;"; + std::unique_ptr stmt_list( + parser.BuildParseTree(query).release()); + EXPECT_TRUE(stmt_list->is_valid); + EXPECT_EQ(StatementType::CREATE, stmt_list->GetStatement(0)->GetType()); + auto create_sequence_stmt = + static_cast(stmt_list->GetStatement(0)); + + // The following code checks the arguments in the create statement + // are identical to what is specified in the query. + + // create type + EXPECT_EQ(parser::CreateStatement::CreateType::kSequence, + create_sequence_stmt->type); + EXPECT_EQ(10, create_sequence_stmt->seq_start); + EXPECT_EQ(2, create_sequence_stmt->seq_increment); + EXPECT_EQ(50, create_sequence_stmt->seq_max_value); + EXPECT_EQ(10, create_sequence_stmt->seq_min_value); + EXPECT_EQ(true, create_sequence_stmt->seq_cycle); +} + +TEST_F(PostgresParserTests, DropSequenceTest) { + auto parser = parser::PostgresParser::GetInstance(); + std::string query = "DROP SEQUENCE seq;"; + std::unique_ptr stmt_list( + parser.BuildParseTree(query).release()); + EXPECT_TRUE(stmt_list->is_valid); + if (!stmt_list->is_valid) { + LOG_ERROR("Message: %s, line: %d, col: %d", stmt_list->parser_msg, + stmt_list->error_line, stmt_list->error_col); + } + EXPECT_EQ(StatementType::DROP, stmt_list->GetStatement(0)->GetType()); + auto drop_sequence_stmt = + static_cast(stmt_list->GetStatement(0)); + // drop type + EXPECT_EQ(parser::DropStatement::EntityType::kSequence, + drop_sequence_stmt->GetDropType()); +} + TEST_F(PostgresParserTests, FuncCallTest) { std::string query = "SELECT add(1,a), chr(99) FROM TEST WHERE FUN(b) > 2"; diff --git a/test/planner/plan_util_test.cpp b/test/planner/plan_util_test.cpp index 77df6f54e88..c5e34563db2 100644 --- a/test/planner/plan_util_test.cpp +++ b/test/planner/plan_util_test.cpp @@ -106,7 +106,7 @@ TEST_F(PlanUtilTests, GetAffectedIndexesTest) { static_cast(sql_stmt) ->table->TryBindDatabaseName(TEST_DB_NAME); std::set affected_indexes = - planner::PlanUtil::GetAffectedIndexes(txn->catalog_cache, *sql_stmt); + planner::PlanUtil::GetAffectedIndexes(txn->GetCatalogCache(), *sql_stmt); // id and first_name are affected EXPECT_EQ(2, static_cast(affected_indexes.size())); @@ -121,7 +121,7 @@ TEST_F(PlanUtilTests, GetAffectedIndexesTest) { static_cast(sql_stmt) ->table->TryBindDatabaseName(TEST_DB_NAME); affected_indexes = - planner::PlanUtil::GetAffectedIndexes(txn->catalog_cache, *sql_stmt); + planner::PlanUtil::GetAffectedIndexes(txn->GetCatalogCache(), *sql_stmt); // only first_name is affected EXPECT_EQ(1, static_cast(affected_indexes.size())); @@ -136,7 +136,7 @@ TEST_F(PlanUtilTests, GetAffectedIndexesTest) { static_cast(sql_stmt) ->TryBindDatabaseName(TEST_DB_NAME); affected_indexes = - planner::PlanUtil::GetAffectedIndexes(txn->catalog_cache, *sql_stmt); + planner::PlanUtil::GetAffectedIndexes(txn->GetCatalogCache(), *sql_stmt); // all indexes are affected EXPECT_EQ(2, static_cast(affected_indexes.size())); @@ -151,7 +151,7 @@ TEST_F(PlanUtilTests, GetAffectedIndexesTest) { static_cast(sql_stmt) ->TryBindDatabaseName(TEST_DB_NAME); affected_indexes = - planner::PlanUtil::GetAffectedIndexes(txn->catalog_cache, *sql_stmt); + planner::PlanUtil::GetAffectedIndexes(txn->GetCatalogCache(), *sql_stmt); // all indexes are affected EXPECT_EQ(2, static_cast(affected_indexes.size())); @@ -164,7 +164,7 @@ TEST_F(PlanUtilTests, GetAffectedIndexesTest) { sql_stmt_list = peloton_parser.BuildParseTree(query_string); sql_stmt = sql_stmt_list->GetStatement(0); affected_indexes = - planner::PlanUtil::GetAffectedIndexes(txn->catalog_cache, *sql_stmt); + planner::PlanUtil::GetAffectedIndexes(txn->GetCatalogCache(), *sql_stmt); // no indexes are affected EXPECT_EQ(0, static_cast(affected_indexes.size())); @@ -262,7 +262,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { bind_node_visitor.BindNameToNode(sql_stmt); std::vector affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); std::set affected_cols(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(2, static_cast(affected_cols.size())); @@ -277,7 +277,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(0, static_cast(affected_cols.size())); @@ -291,7 +291,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(0, static_cast(affected_cols.size())); @@ -304,7 +304,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(2, static_cast(affected_cols.size())); @@ -320,7 +320,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(0, static_cast(affected_cols.size())); @@ -334,7 +334,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(2, static_cast(affected_cols.size())); @@ -350,7 +350,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(3, static_cast(affected_cols.size())); @@ -370,7 +370,7 @@ TEST_F(PlanUtilTests, GetIndexableColumnsTest) { sql_stmt = sql_stmt_list->GetStatement(0); bind_node_visitor.BindNameToNode(sql_stmt); affected_cols_vector = planner::PlanUtil::GetIndexableColumns( - txn->catalog_cache, std::move(sql_stmt_list), TEST_DB_COLUMNS); + txn->GetCatalogCache(), std::move(sql_stmt_list), TEST_DB_COLUMNS); affected_cols = std::set(affected_cols_vector.begin(), affected_cols_vector.end()); EXPECT_EQ(2, static_cast(affected_cols.size())); From f50bf180d038cf43eb5772213b926d9eb84696bf Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Tue, 12 Jun 2018 13:22:37 -0400 Subject: [PATCH 2/9] Added SequenceCatalogTests. This is working. --- test/catalog/sequence_catalog_test.cpp | 284 +++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 test/catalog/sequence_catalog_test.cpp diff --git a/test/catalog/sequence_catalog_test.cpp b/test/catalog/sequence_catalog_test.cpp new file mode 100644 index 00000000000..8f6df5d85e5 --- /dev/null +++ b/test/catalog/sequence_catalog_test.cpp @@ -0,0 +1,284 @@ +//===----------------------------------------------------------------------===// +// +// Peloton +// +// sequence_test.cpp +// +// Identification: test/sequence/sequence_test.cpp +// +// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include "catalog/catalog.h" +#include "catalog/sequence_catalog.h" +#include "storage/abstract_table.h" +#include "common/harness.h" +#include "common/exception.h" +#include "executor/executors.h" +#include "executor/executor_context.h" +#include "parser/postgresparser.h" +#include "planner/create_plan.h" +#include "planner/insert_plan.h" +#include "concurrency/transaction_manager_factory.h" + +namespace peloton { +namespace test { + +class SequenceCatalogTests : public PelotonTest { + protected: + void CreateDatabaseHelper() { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + catalog::Catalog::GetInstance()->Bootstrap(); + catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn); + txn_manager.CommitTransaction(txn); + } + + std::shared_ptr GetSequenceHelper( + std::string sequence_name, concurrency::TransactionContext *txn) { + // Check the effect of creation + oid_t database_oid = catalog::Catalog::GetInstance() + ->GetDatabaseWithName(DEFAULT_DB_NAME, txn) + ->GetOid(); + std::shared_ptr new_sequence = + catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_oid) + ->GetSequenceCatalog() + ->GetSequence(database_oid, sequence_name, txn); + + return new_sequence; + } + + void CreateSequenceHelper(std::string query, + concurrency::TransactionContext *txn) { + auto parser = parser::PostgresParser::GetInstance(); + + std::unique_ptr stmt_list( + parser.BuildParseTree(query).release()); + EXPECT_TRUE(stmt_list->is_valid); + EXPECT_EQ(StatementType::CREATE, stmt_list->GetStatement(0)->GetType()); + auto create_sequence_stmt = + static_cast(stmt_list->GetStatement(0)); + + create_sequence_stmt->TryBindDatabaseName(DEFAULT_DB_NAME); + // Create plans + planner::CreatePlan plan(create_sequence_stmt); + + // plan type + EXPECT_EQ(CreateType::SEQUENCE, plan.GetCreateType()); + + // Execute the create sequence + std::unique_ptr context( + new executor::ExecutorContext(txn, {})); + executor::CreateExecutor createSequenceExecutor(&plan, context.get()); + createSequenceExecutor.Init(); + createSequenceExecutor.Execute(); + } + + void DropSequenceHelper(std::string query, + concurrency::TransactionContext *txn) { + auto parser = parser::PostgresParser::GetInstance(); + + std::unique_ptr stmt_list( + parser.BuildParseTree(query).release()); + EXPECT_TRUE(stmt_list->is_valid); + EXPECT_EQ(StatementType::DROP, stmt_list->GetStatement(0)->GetType()); + auto drop_sequence_stmt = + static_cast(stmt_list->GetStatement(0)); + + drop_sequence_stmt->TryBindDatabaseName(DEFAULT_DB_NAME); + // Drop plans + planner::DropPlan plan(drop_sequence_stmt); + + // Plan type + EXPECT_EQ(DropType::SEQUENCE, plan.GetDropType()); + + // Execute the drop sequence + std::unique_ptr context( + new executor::ExecutorContext(txn)); + executor::DropExecutor dropSequenceExecutor(&plan, context.get()); + dropSequenceExecutor.Init(); + dropSequenceExecutor.Execute(); + } +}; + +TEST_F(SequenceCatalogTests, BasicTest) { + CreateDatabaseHelper(); + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + // Create statement + std::string query = + "CREATE SEQUENCE seq " + "INCREMENT BY 2 " + "MINVALUE 10 MAXVALUE 50 " + "START 10 CYCLE;"; + std::string name = "seq"; + + CreateSequenceHelper(query, txn); + std::shared_ptr new_sequence = + GetSequenceHelper(name, txn); + + EXPECT_EQ(name, new_sequence->seq_name); + EXPECT_EQ(2, new_sequence->seq_increment); + EXPECT_EQ(10, new_sequence->seq_min); + EXPECT_EQ(50, new_sequence->seq_max); + EXPECT_EQ(10, new_sequence->seq_start); + EXPECT_EQ(true, new_sequence->seq_cycle); + EXPECT_EQ(10, new_sequence->GetNextVal()); + EXPECT_EQ(10, new_sequence->GetCurrVal()); + + txn_manager.CommitTransaction(txn); +} + +TEST_F(SequenceCatalogTests, NoDuplicateTest) { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + // Create statement + std::string query = + "CREATE SEQUENCE seq " + "INCREMENT BY 2 " + "MINVALUE 10 MAXVALUE 50 " + "START 10 CYCLE;"; + std::string name = "seq"; + + // Expect exception + EXPECT_THROW(CreateSequenceHelper(query, txn), peloton::SequenceException); + txn_manager.CommitTransaction(txn); +} + +TEST_F(SequenceCatalogTests, DropTest) { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + // Create statement + std::string query = + "CREATE SEQUENCE seq " + "INCREMENT BY 2 " + "MINVALUE 10 MAXVALUE 50 " + "START 10 CYCLE;"; + + // Drop statement + std::string dropQuery = + "DROP SEQUENCE seq"; + + // Expect exception + EXPECT_THROW(CreateSequenceHelper(query, txn), peloton::SequenceException); + + // FIXME: The DROP SEQUENCE should fail here because the sequence shouldn't exist. + DropSequenceHelper(dropQuery, txn); + CreateSequenceHelper(query, txn); + + txn_manager.CommitTransaction(txn); +} + +TEST_F(SequenceCatalogTests, NextValPosIncrementFunctionalityTest) { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + std::string query = + "CREATE SEQUENCE seq1 " + "INCREMENT BY 1 " + "MINVALUE 10 MAXVALUE 50 " + "START 10 CYCLE;"; + std::string name = "seq1"; + + CreateSequenceHelper(query, txn); + std::shared_ptr new_sequence = + GetSequenceHelper(name, txn); + + int64_t nextVal = new_sequence->GetNextVal(); + EXPECT_EQ(10, nextVal); + nextVal = new_sequence->GetNextVal(); + EXPECT_EQ(11, nextVal); + + // test cycle + new_sequence->SetCurrVal(50); + nextVal = new_sequence->GetNextVal(); + nextVal = new_sequence->GetNextVal(); + EXPECT_EQ(10, nextVal); + + // test no cycle + new_sequence->SetCycle(false); + new_sequence->SetCurrVal(50); + + // Expect exception + EXPECT_THROW(new_sequence->GetNextVal(), peloton::SequenceException); + + txn_manager.CommitTransaction(txn); +} + +TEST_F(SequenceCatalogTests, NextValNegIncrementFunctionalityTest) { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + std::string query = + "CREATE SEQUENCE seq2 " + "INCREMENT BY -1 " + "MINVALUE 10 MAXVALUE 50 " + "START 10 CYCLE;"; + std::string name = "seq2"; + + CreateSequenceHelper(query, txn); + std::shared_ptr new_sequence = + GetSequenceHelper(name, txn); + + // test cycle + int64_t nextVal = new_sequence->GetNextVal(); + EXPECT_EQ(10, nextVal); + nextVal = new_sequence->GetNextVal(); + EXPECT_EQ(50, nextVal); + + new_sequence->SetCurrVal(49); + nextVal = new_sequence->GetNextVal(); + nextVal = new_sequence->GetNextVal(); + EXPECT_EQ(48, nextVal); + + // test no cycle + new_sequence->SetCycle(false); + new_sequence->SetCurrVal(10); + + // Expect exception + EXPECT_THROW(new_sequence->GetNextVal(), peloton::SequenceException); + + txn_manager.CommitTransaction(txn); +} + +TEST_F(SequenceCatalogTests, InvalidArgumentTest) { + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); + auto txn = txn_manager.BeginTransaction(); + + std::string query = + "CREATE SEQUENCE seq3 " + "INCREMENT BY -1 " + "MINVALUE 50 MAXVALUE 10 " + "START 10 CYCLE;"; + EXPECT_THROW(CreateSequenceHelper(query, txn), peloton::SequenceException); + + query = + "CREATE SEQUENCE seq3 " + "INCREMENT BY 0 " + "MINVALUE 10 MAXVALUE 50 " + "START 10 CYCLE;"; + EXPECT_THROW(CreateSequenceHelper(query, txn), peloton::SequenceException); + + query = + "CREATE SEQUENCE seq3 " + "INCREMENT BY 1 " + "MINVALUE 10 MAXVALUE 50 " + "START 8 CYCLE;"; + EXPECT_THROW(CreateSequenceHelper(query, txn), peloton::SequenceException); + + query = + "CREATE SEQUENCE seq3 " + "INCREMENT BY -1 " + "MINVALUE 10 MAXVALUE 50 " + "START 60 CYCLE;"; + EXPECT_THROW(CreateSequenceHelper(query, txn), peloton::SequenceException); + + txn_manager.CommitTransaction(txn); +} +} +} From 2d3fab887e3253c2932e72831a7f66876e55d94e Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Thu, 14 Jun 2018 09:58:59 -0400 Subject: [PATCH 3/9] Fixing comments for CatalogCache methods --- src/catalog/catalog_cache.cpp | 67 ++--------- src/catalog/sequence_catalog.cpp | 53 +-------- src/function/sequence_functions.cpp | 19 ++-- src/include/catalog/catalog_cache.h | 54 ++++++++- src/include/catalog/sequence_catalog.h | 128 +++++++++++++++++++--- test/function/sequence_functions_test.cpp | 19 ++-- 6 files changed, 194 insertions(+), 146 deletions(-) diff --git a/src/catalog/catalog_cache.cpp b/src/catalog/catalog_cache.cpp index 90f6aefbbb2..22cd428a89f 100644 --- a/src/catalog/catalog_cache.cpp +++ b/src/catalog/catalog_cache.cpp @@ -86,10 +86,6 @@ bool CatalogCache::EvictDatabaseObject(const std::string &database_name) { return true; } -/*@brief get database catalog object from cache - * @param database_oid - * @return database catalog object; if not found return object with invalid oid - */ std::shared_ptr CatalogCache::GetDatabaseObject( oid_t database_oid) { auto it = database_objects_cache.find(database_oid); @@ -99,10 +95,6 @@ std::shared_ptr CatalogCache::GetDatabaseObject( return it->second; } -/*@brief get database catalog object from cache - * @param database_name - * @return database catalog object; if not found return null - */ std::shared_ptr CatalogCache::GetDatabaseObject( const std::string &database_name) { auto it = database_name_cache.find(database_name); @@ -120,10 +112,6 @@ std::vector> CatalogCache::GetAllDatabase return (databases); } -/*@brief search table catalog object from all cached database objects - * @param table_oid - * @return table catalog object; if not found return null - */ std::shared_ptr CatalogCache::GetCachedTableObject( oid_t database_oid, oid_t table_oid) { auto database_object = GetDatabaseObject(database_oid); @@ -133,10 +121,6 @@ std::shared_ptr CatalogCache::GetCachedTableObject( return nullptr; } -/*@brief search index catalog object from all cached database objects - * @param index_oid - * @return index catalog object; if not found return null - */ std::shared_ptr CatalogCache::GetCachedIndexObject( oid_t database_oid, oid_t index_oid) { auto database_object = GetDatabaseObject(database_oid); @@ -146,10 +130,6 @@ std::shared_ptr CatalogCache::GetCachedIndexObject( return nullptr; } -/*@brief search index catalog object from all cached database objects - * @param index_name - * @return index catalog object; if not found return null - */ std::shared_ptr CatalogCache::GetCachedIndexObject( const std::string &database_name, const std::string &index_name, const std::string &schema_name) { @@ -161,43 +141,32 @@ std::shared_ptr CatalogCache::GetCachedIndexObject( return nullptr; } -/*@brief insert sequence catalog object into cache - * @param sequence_object - * @return false only if sequence already exists in cache or invalid - */ bool CatalogCache::InsertSequenceObject( std::shared_ptr sequence_object) { - if (!sequence_object || sequence_object->seq_oid == INVALID_OID) { + if (!sequence_object || sequence_object->GetSequenceOid() == INVALID_OID) { return false; // invalid object } - std::size_t hash_key = GetHashKey(sequence_object->seq_name, - sequence_object->db_oid); + std::pair key = std::make_pair(sequence_object->GetDatabaseOid(), + sequence_object->GetName()); // check if already in cache - if (sequence_objects_cache.find(hash_key) != + if (sequence_objects_cache.find(key) != sequence_objects_cache.end()) { LOG_DEBUG("Sequence %s already exists in cache!", - sequence_object->seq_name.c_str()); + sequence_object->GetName().c_str()); return false; } sequence_objects_cache.insert( - std::make_pair(hash_key, sequence_object)); + std::make_pair(key, sequence_object)); return true; } -/*@brief evict sequence catalog object from cache - * @param sequence_name - * @param database_oid - * @return true if specified sequence is found and evicted; - * false if not found - */ bool CatalogCache::EvictSequenceObject(const std::string & sequence_name, oid_t database_oid) { - std::size_t hash_key = GetHashKey(sequence_name, database_oid); - - auto it = sequence_objects_cache.find(hash_key); + std::pair key = std::make_pair(database_oid, sequence_name); + auto it = sequence_objects_cache.find(key); if (it == sequence_objects_cache.end()) { return false; // sequence not found in cache } @@ -208,32 +177,16 @@ bool CatalogCache::EvictSequenceObject(const std::string & sequence_name, return true; } -/*@brief get sequence catalog object from cache - * @param sequence_name - * @param database_oid - * @return sequence catalog object; if not found return object with invalid oid - */ std::shared_ptr CatalogCache::GetSequenceObject( const std::string & sequence_name, oid_t database_oid) { - std::size_t hash_key = GetHashKey(sequence_name, database_oid); - auto it = sequence_objects_cache.find(hash_key); + std::pair key = std::make_pair(database_oid, sequence_name); + auto it = sequence_objects_cache.find(key); if (it == sequence_objects_cache.end()) { return nullptr; } return it->second; } -/*@brief get the hash key given the sequence information - * @param sequence_name - * @param database_oid - * @return hash key - */ -std::size_t CatalogCache::GetHashKey(const std::string sequence_name, - oid_t database_oid) { - std::tuple key(sequence_name, database_oid); - boost::hash> key_hash; - return key_hash(key); -} } // namespace catalog } // namespace peloton diff --git a/src/catalog/sequence_catalog.cpp b/src/catalog/sequence_catalog.cpp index 55c47069050..0420a422575 100644 --- a/src/catalog/sequence_catalog.cpp +++ b/src/catalog/sequence_catalog.cpp @@ -30,11 +30,6 @@ namespace peloton { namespace catalog { -/* @brief Get the nextval of the sequence - * @return the next value of the sequence. - * @exception throws SequenceException if the sequence exceeds the upper/lower - * limit. - */ int64_t SequenceCatalogObject::GetNextVal() { int64_t result = seq_curr_val; seq_prev_val = result; @@ -93,20 +88,7 @@ SequenceCatalog::SequenceCatalog(const std::string &database_name, SequenceCatalog::~SequenceCatalog() {} -/* @brief Insert the sequence by name. - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence - * @param seq_increment the increment per step of the sequence - * @param seq_max the max value of the sequence - * @param seq_min the min value of the sequence - * @param seq_start the start of the sequence - * @param seq_cycle whether the sequence cycles - * @param pool an instance of abstract pool - * @param txn current transaction - * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE - * otherwise. - * @exception throws SequenceException if the sequence already exists. - */ + bool SequenceCatalog::InsertSequence(oid_t database_oid, std::string sequence_name, int64_t seq_increment, int64_t seq_max, @@ -151,13 +133,6 @@ bool SequenceCatalog::InsertSequence(oid_t database_oid, return InsertTuple(std::move(tuple), txn); } -/* @brief Delete the sequence by name. - * @param database_name the database name associated with the sequence - * @param sequence_name the name of the sequence - * @param txn current transaction - * @return ResultType::SUCCESS if the sequence exists, throw exception - * otherwise. - */ ResultType SequenceCatalog::DropSequence(const std::string &database_name, const std::string &sequence_name, concurrency::TransactionContext *txn) { @@ -188,12 +163,6 @@ ResultType SequenceCatalog::DropSequence(const std::string &database_name, return ResultType::SUCCESS; } -/* @brief Delete the sequence by name. The sequence is guaranteed to exist. - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence - * @param txn current transaction - * @return The result of DeleteWithIndexScan. - */ bool SequenceCatalog::DeleteSequenceByName( const std::string &sequence_name, oid_t database_oid, concurrency::TransactionContext *txn) { @@ -205,12 +174,6 @@ bool SequenceCatalog::DeleteSequenceByName( return DeleteWithIndexScan(index_offset, values, txn); } -/* @brief get sequence from pg_sequence table - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence - * @param txn current transaction - * @return a SequenceCatalogObject if the sequence is found, nullptr otherwise - */ std::shared_ptr SequenceCatalog::GetSequence( oid_t database_oid, const std::string &sequence_name, concurrency::TransactionContext *txn) { @@ -254,12 +217,6 @@ std::shared_ptr SequenceCatalog::GetSequence( return new_sequence; } -/* @brief update the next value of the sequence in the underlying storage - * @param sequence_oid the sequence_oid of the sequence - * @param nextval the nextval of the sequence - * @param txn current transaction - * @return the result of the transaction - */ bool SequenceCatalog::UpdateNextVal(oid_t sequence_oid, int64_t nextval, concurrency::TransactionContext *txn){ std::vector update_columns({SequenceCatalog::ColumnId::SEQUENCE_VALUE}); @@ -272,14 +229,6 @@ bool SequenceCatalog::UpdateNextVal(oid_t sequence_oid, int64_t nextval, return UpdateWithIndexScan(update_columns, update_values, scan_values, index_offset, txn); } -/* @brief get sequence oid from pg_sequence table given sequence_name and - * database_oid - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence - * @param txn current transaction - * @return the oid_t of the sequence if the sequence is found, INVALID_OID - * otherwise - */ oid_t SequenceCatalog::GetSequenceOid(std::string sequence_name, oid_t database_oid, concurrency::TransactionContext *txn) { diff --git a/src/function/sequence_functions.cpp b/src/function/sequence_functions.cpp index 44962f9a088..a6b992bf6d6 100644 --- a/src/function/sequence_functions.cpp +++ b/src/function/sequence_functions.cpp @@ -42,23 +42,24 @@ uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, auto database_catalog = all_databases[0]; LOG_DEBUG("Get database oid: %u", database_catalog->GetDatabaseOid()); + auto sequence_catalog = catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) + ->GetSequenceCatalog(); + // initialize a new transaction for incrementing sequence value auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto mini_txn = txn_manager.BeginTransaction(); // evict the old cached copy of sequence - txn->GetCatalogCache()->EvictSequenceObject(sequence_name, - database_catalog->GetDatabaseOid()); - auto sequence_object = - catalog::Catalog::GetInstance() - ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) - ->GetSequenceCatalog() - ->GetSequence(database_catalog->GetDatabaseOid(), - sequence_name, mini_txn); +// txn->GetCatalogCache()->EvictSequenceObject(sequence_name, +// database_catalog->GetDatabaseOid()); + auto sequence_object = sequence_catalog + ->GetSequence(database_catalog->GetDatabaseOid(), sequence_name, mini_txn); if (sequence_object != nullptr) { - uint32_t val = sequence_object->GetNextVal(); + int64_t val = sequence_object->GetNextVal(); int64_t curr_val = sequence_object->GetCurrVal(); + // insert the new copy of sequence into cache for future currval txn->GetCatalogCache()->InsertSequenceObject(sequence_object); diff --git a/src/include/catalog/catalog_cache.h b/src/include/catalog/catalog_cache.h index 6c39ea54cca..56856a34a6c 100644 --- a/src/include/catalog/catalog_cache.h +++ b/src/include/catalog/catalog_cache.h @@ -52,7 +52,19 @@ class CatalogCache { CatalogCache &operator=(CatalogCache const &) = delete; private: + + /** + * @brief get database catalog object from cache + * @param database_oid + * @return database catalog object; if not found return object with invalid oid + */ std::shared_ptr GetDatabaseObject(oid_t database_oid); + + /** + * @brief get database catalog object from cache + * @param database_name + * @return database catalog object; if not found return null + */ std::shared_ptr GetDatabaseObject( const std::string &name); @@ -62,8 +74,25 @@ class CatalogCache { */ std::vector> GetAllDatabaseObjects(); + /** + * @brief search table catalog object from all cached database objects + * @param table_oid + * @return table catalog object; if not found return null + */ std::shared_ptr GetCachedTableObject(oid_t database_oid, oid_t table_oid); + + /** + * @brief search index catalog object from all cached database objects + * @param index_oid + * @return index catalog object; if not found return null + */ std::shared_ptr GetCachedIndexObject(oid_t database_oid, oid_t index_oid); + + /** + * @brief search index catalog object from all cached database objects + * @param index_name + * @return index catalog object; if not found return null + */ std::shared_ptr GetCachedIndexObject( const std::string &database_name, const std::string &index_name, const std::string &schema_name); @@ -74,14 +103,32 @@ class CatalogCache { bool EvictDatabaseObject(oid_t database_oid); bool EvictDatabaseObject(const std::string &database_name); - // sequence catalog cache interface + /** + * @brief insert sequence catalog object into cache + * @param sequence_object + * @return false only if sequence already exists in cache or invalid + */ bool InsertSequenceObject( std::shared_ptr sequence_object); + + /** + * @brief evict sequence catalog object from cache + * @param sequence_name + * @param database_oid + * @return true if specified sequence is found and evicted; + * false if not found + */ bool EvictSequenceObject(const std::string &sequence_name, oid_t database_oid); + + /** + * @brief get sequence catalog object from cache + * @param sequence_name + * @param database_oid + * @return sequence catalog object; if not found return object with invalid oid + */ std::shared_ptr GetSequenceObject( const std::string &sequence_name, oid_t database_oid); - std::size_t GetHashKey(std::string sequence_name, oid_t database_oid); // cache for database catalog object std::unordered_map> @@ -90,7 +137,8 @@ class CatalogCache { database_name_cache; // cache for sequence catalog object - std::unordered_map> + std::unordered_map, + std::shared_ptr> sequence_objects_cache; }; diff --git a/src/include/catalog/sequence_catalog.h b/src/include/catalog/sequence_catalog.h index e75ffb198b0..0f43e32102c 100644 --- a/src/include/catalog/sequence_catalog.h +++ b/src/include/catalog/sequence_catalog.h @@ -64,35 +64,80 @@ class SequenceCatalogObject { seq_max(seqmax), seq_min(seqmin), seq_cycle(seqcycle), - txn_(txn), - seq_curr_val(seqval){}; + seq_curr_val(seqval), + txn_(txn) {}; - oid_t seq_oid; - oid_t db_oid; - std::string seq_name; - int64_t seq_start; // Start value of the sequence - int64_t seq_increment; // Increment value of the sequence - int64_t seq_max; // Maximum value of the sequence - int64_t seq_min; // Minimum value of the sequence - int64_t seq_cache; // Cache size of the sequence - bool seq_cycle; // Whether the sequence cycles - concurrency::TransactionContext *txn_; - int64_t seq_prev_val; + oid_t GetSequenceOid() const { + return (seq_oid); + } + + oid_t GetDatabaseOid() const { + return (db_oid); + } + + std::string GetName() const { + return (seq_name); + } + + int64_t GetStart() const { + return (seq_start); + } + + int64_t GetIncrement() const { + return (seq_increment); + } + + int64_t GetMax() const { + return (seq_max); + } + + int64_t GetMin() const { + return (seq_min); + } + int64_t GetCacheSize() const { + return (seq_cache); + } + + bool GetAllowCycle() const { + return (seq_cycle); + } + + /** + * @brief Get the nextval of the sequence + * @exception throws SequenceException if the sequence exceeds the upper/lower limit + * @return + */ int64_t GetNextVal(); - int64_t GetCurrVal() { + int64_t GetCurrVal() const { return seq_prev_val; - }; + } + + protected: + + void SetCycle(bool cycle) { seq_cycle = cycle; }; void SetCurrVal(int64_t curr_val) { seq_curr_val = curr_val; }; // only visible for test! - void SetCycle(bool cycle) { seq_cycle = cycle; }; private: + oid_t seq_oid; + oid_t db_oid; + std::string seq_name; + int64_t seq_start; // Start value of the sequence + int64_t seq_increment; // Increment value of the sequence + int64_t seq_max; // Maximum value of the sequence + int64_t seq_min; // Minimum value of the sequence + int64_t seq_cache; // Cache size of the sequence + bool seq_cycle; // Whether the sequence cycles int64_t seq_curr_val; + + concurrency::TransactionContext *txn_; + + int64_t seq_prev_val; }; class SequenceCatalog : public AbstractCatalog { @@ -104,27 +149,78 @@ class SequenceCatalog : public AbstractCatalog { //===--------------------------------------------------------------------===// // write Related API //===--------------------------------------------------------------------===// + + /** + * @brief Insert the sequence by name. + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param seq_increment the increment per step of the sequence + * @param seq_max the max value of the sequence + * @param seq_min the min value of the sequence + * @param seq_start the start of the sequence + * @param seq_cycle whether the sequence cycles + * @param pool an instance of abstract pool + * @param txn current transaction + * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE otherwise. + * @exception throws SequenceException if the sequence already exists. + */ bool InsertSequence(oid_t database_oid, std::string sequence_name, int64_t seq_increment, int64_t seq_max, int64_t seq_min, int64_t seq_start, bool seq_cycle, type::AbstractPool *pool, concurrency::TransactionContext *txn); + /** + * @brief Delete the sequence by name. + * @param database_name the database name associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return ResultType::SUCCESS if the sequence exists, throw exception otherwise. + */ ResultType DropSequence(const std::string &database_name, const std::string &sequence_name, concurrency::TransactionContext *txn); + /** + * @brief Delete the sequence by name. The sequence is guaranteed to exist. + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return The result of DeleteWithIndexScan. + */ bool DeleteSequenceByName(const std::string &sequence_name, oid_t database_oid, concurrency::TransactionContext *txn); + /** + * @brief get sequence from pg_sequence table + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return a SequenceCatalogObject if the sequence is found, nullptr otherwise + */ std::shared_ptr GetSequence( oid_t database_oid, const std::string &sequence_name, concurrency::TransactionContext *txn); + /** + * @brief get sequence oid from pg_sequence given sequence_name and database_oid + * @param database_oid the databse_oid associated with the sequence + * @param sequence_name the name of the sequence + * @param txn current transaction + * @return the oid_t of the sequence if the sequence is found, INVALID_OI otherwise + */ oid_t GetSequenceOid(std::string sequence_name, oid_t database_oid, concurrency::TransactionContext *txn); + /** + * @brief update the next value of the sequence in the underlying storage + * @param sequence_oid the sequence_oid of the sequence + * @param nextval the nextval of the sequence + * @param txn current transaction + * @return the result of the transaction + * @return + */ bool UpdateNextVal(oid_t sequence_oid, int64_t nextval, concurrency::TransactionContext *txn); diff --git a/test/function/sequence_functions_test.cpp b/test/function/sequence_functions_test.cpp index 1072c378e6c..5f382433c21 100644 --- a/test/function/sequence_functions_test.cpp +++ b/test/function/sequence_functions_test.cpp @@ -35,7 +35,8 @@ namespace test { class SequenceFunctionsTests : public PelotonTest { protected: - void CreateDatabaseHelper() { + + void SetUp() override { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->Bootstrap(); @@ -70,8 +71,7 @@ class SequenceFunctionsTests : public PelotonTest { } }; -TEST_F(SequenceFunctionsTests, BasicTest) { - CreateDatabaseHelper(); +TEST_F(SequenceFunctionsTests, DISABLED_CreateTest) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); @@ -85,16 +85,17 @@ TEST_F(SequenceFunctionsTests, BasicTest) { TEST_F(SequenceFunctionsTests, FunctionsTest) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); + + // HACK: This is needed to prime the CatalogCache. + // We can remove this once we add SessionContext + catalog::Catalog::GetInstance()->GetDatabaseObject(DEFAULT_DB_NAME, txn); + std::unique_ptr context( new executor::ExecutorContext(txn, {})); // Expect exception - try { - function::SequenceFunctions::Currval(*(context.get()), "seq"); - EXPECT_EQ(0, 1); - } catch (const SequenceException &expected) { - ASSERT_STREQ("currval for sequence \"seq\" is undefined for this session", expected.what()); - } + EXPECT_THROW(function::SequenceFunctions::Currval(*(context.get()), "seq"), + peloton::SequenceException); // Check nextval & currval functionality auto res = function::SequenceFunctions::Nextval(*(context.get()), "seq"); From 42f5cd0052863c9e4c1a2cda40ca781467604ac2 Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Fri, 22 Jun 2018 06:23:15 -0400 Subject: [PATCH 4/9] Trying to clean up the SequenceCatalogObject code... --- src/catalog/sequence_catalog.cpp | 96 ++++++++-------- src/include/catalog/sequence_catalog.h | 152 ++++++++++--------------- 2 files changed, 107 insertions(+), 141 deletions(-) diff --git a/src/catalog/sequence_catalog.cpp b/src/catalog/sequence_catalog.cpp index 0420a422575..3bf47c685a8 100644 --- a/src/catalog/sequence_catalog.cpp +++ b/src/catalog/sequence_catalog.cpp @@ -82,7 +82,7 @@ SequenceCatalog::SequenceCatalog(const std::string &database_name, txn) { Catalog::GetInstance()->CreateIndex( database_name, CATALOG_SCHEMA_NAME, SEQUENCE_CATALOG_NAME, - {ColumnId::DATABSE_OID, ColumnId::SEQUENCE_NAME}, + {ColumnId::DATABASE_OID, ColumnId::SEQUENCE_NAME}, SEQUENCE_CATALOG_NAME "_skey0", false, IndexType::BWTREE, txn); } @@ -90,6 +90,7 @@ SequenceCatalog::~SequenceCatalog() {} bool SequenceCatalog::InsertSequence(oid_t database_oid, + oid_t namespace_oid, std::string sequence_name, int64_t seq_increment, int64_t seq_max, int64_t seq_min, int64_t seq_start, @@ -99,7 +100,7 @@ bool SequenceCatalog::InsertSequence(oid_t database_oid, LOG_DEBUG("Insert Sequence Sequence Name: %s", sequence_name.c_str()); ValidateSequenceArguments(seq_increment, seq_max, seq_min, seq_start); - if (GetSequence(database_oid, sequence_name, txn) != nullptr) { + if (GetSequence(database_oid, namespace_oid, sequence_name, txn) != nullptr) { throw SequenceException( StringUtil::Format("Sequence %s already exists!", sequence_name.c_str())); @@ -108,47 +109,45 @@ bool SequenceCatalog::InsertSequence(oid_t database_oid, std::unique_ptr tuple( new storage::Tuple(catalog_table_->GetSchema(), true)); - auto val0 = type::ValueFactory::GetIntegerValue(GetNextOid()); - auto val1 = type::ValueFactory::GetIntegerValue(database_oid); - auto val2 = type::ValueFactory::GetVarcharValue(sequence_name); - auto val3 = type::ValueFactory::GetBigIntValue(seq_increment); - auto val4 = type::ValueFactory::GetBigIntValue(seq_max); - auto val5 = type::ValueFactory::GetBigIntValue(seq_min); - auto val6 = type::ValueFactory::GetBigIntValue(seq_start); - auto val7 = type::ValueFactory::GetBooleanValue(seq_cycle); + tuple->SetValue(ColumnId::SEQUENCE_OID, + type::ValueFactory::GetIntegerValue(GetNextOid()), pool); + tuple->SetValue(ColumnId::DATABASE_OID, + type::ValueFactory::GetIntegerValue(database_oid), pool); + tuple->SetValue(ColumnId::NAMESPACE_OID, + type::ValueFactory::GetIntegerValue(namespace_oid), pool); + tuple->SetValue(ColumnId::SEQUENCE_NAME, + type::ValueFactory::GetVarcharValue(sequence_name), pool); + tuple->SetValue(ColumnId::SEQUENCE_INC, + type::ValueFactory::GetBigIntValue(seq_increment), pool); + tuple->SetValue(ColumnId::SEQUENCE_MAX, + type::ValueFactory::GetBigIntValue(seq_max), pool); + tuple->SetValue(ColumnId::SEQUENCE_MIN, + type::ValueFactory::GetBigIntValue(seq_min), pool); + tuple->SetValue(ColumnId::SEQUENCE_START, + type::ValueFactory::GetBigIntValue(seq_start), pool); + tuple->SetValue(ColumnId::SEQUENCE_CYCLE, + type::ValueFactory::GetBooleanValue(seq_cycle), pool); // When insert value, seqval = seq_start - auto val8 = type::ValueFactory::GetBigIntValue(seq_start); - - tuple->SetValue(ColumnId::SEQUENCE_OID, val0, pool); - tuple->SetValue(ColumnId::DATABSE_OID, val1, pool); - tuple->SetValue(ColumnId::SEQUENCE_NAME, val2, pool); - tuple->SetValue(ColumnId::SEQUENCE_INC, val3, pool); - tuple->SetValue(ColumnId::SEQUENCE_MAX, val4, pool); - tuple->SetValue(ColumnId::SEQUENCE_MIN, val5, pool); - tuple->SetValue(ColumnId::SEQUENCE_START, val6, pool); - tuple->SetValue(ColumnId::SEQUENCE_CYCLE, val7, pool); - tuple->SetValue(ColumnId::SEQUENCE_VALUE, val8, pool); + tuple->SetValue(ColumnId::SEQUENCE_VALUE, + type::ValueFactory::GetBigIntValue(seq_start), pool); // Insert the tuple return InsertTuple(std::move(tuple), txn); } -ResultType SequenceCatalog::DropSequence(const std::string &database_name, - const std::string &sequence_name, - concurrency::TransactionContext *txn) { +ResultType SequenceCatalog::DropSequence( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name) { if (txn == nullptr) { throw CatalogException("Transaction is invalid!"); } - auto database_object = - Catalog::GetInstance()->GetDatabaseObject(database_name, txn); - - oid_t database_oid = database_object->GetDatabaseOid(); - oid_t sequence_oid = Catalog::GetInstance() ->GetSystemCatalogs(database_oid) ->GetSequenceCatalog() - ->GetSequenceOid(sequence_name, database_oid, txn); + ->GetSequenceOid(txn, database_oid, namespace_oid, sequence_name); if (sequence_oid == INVALID_OID) { throw SequenceException( StringUtil::Format("Sequence %s does not exist!", @@ -157,34 +156,34 @@ ResultType SequenceCatalog::DropSequence(const std::string &database_name, LOG_INFO("sequence %d will be deleted!", sequence_oid); - DeleteSequenceByName(sequence_name, database_oid, txn); - EvictSequenceNameCurrValCache(sequence_name); - - return ResultType::SUCCESS; -} - -bool SequenceCatalog::DeleteSequenceByName( - const std::string &sequence_name, oid_t database_oid, - concurrency::TransactionContext *txn) { oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); - return DeleteWithIndexScan(index_offset, values, txn); + // TODO: Check return result + DeleteWithIndexScan(index_offset, values, txn); + + return ResultType::SUCCESS; } std::shared_ptr SequenceCatalog::GetSequence( - oid_t database_oid, const std::string &sequence_name, - concurrency::TransactionContext *txn) { + concurrency::TransactionContext *txn, + oid_t database_oid, oid_t namespace_oid, const std::string &sequence_name) { std::vector column_ids( - {ColumnId::SEQUENCE_OID, ColumnId::SEQUENCE_START, - ColumnId::SEQUENCE_INC, ColumnId::SEQUENCE_MAX, - ColumnId::SEQUENCE_MIN, ColumnId::SEQUENCE_CYCLE, - ColumnId::SEQUENCE_VALUE}); - oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; + {ColumnId::SEQUENCE_OID, + ColumnId::SEQUENCE_START, + ColumnId::SEQUENCE_INC, + ColumnId::SEQUENCE_MAX, + ColumnId::SEQUENCE_MIN, + ColumnId::SEQUENCE_CYCLE, + ColumnId::SEQUENCE_VALUE} + ); + + oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + values.push_back(type::ValueFactory::GetIntegerValue(namespace_oid).Copy()); values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); // the result is a vector of executor::LogicalTile @@ -192,7 +191,7 @@ std::shared_ptr SequenceCatalog::GetSequence( GetResultWithIndexScan(column_ids, index_offset, values, txn); // careful! the result tile could be null! if (result_tiles == nullptr || result_tiles->size() == 0) { - LOG_INFO("no sequence on database %d and %s", database_oid, + LOG_WARN("No sequence on database %d and %s", database_oid, sequence_name.c_str()); return std::shared_ptr(nullptr); } else { @@ -206,6 +205,7 @@ std::shared_ptr SequenceCatalog::GetSequence( auto new_sequence = std::make_shared( (*result_tiles)[0]->GetValue(0, 0).GetAs(), database_oid, + namespace_oid, sequence_name, (*result_tiles)[0]->GetValue(0, 1).GetAs(), (*result_tiles)[0]->GetValue(0, 2).GetAs(), diff --git a/src/include/catalog/sequence_catalog.h b/src/include/catalog/sequence_catalog.h index 0f43e32102c..b9a7d7104f6 100644 --- a/src/include/catalog/sequence_catalog.h +++ b/src/include/catalog/sequence_catalog.h @@ -11,22 +11,23 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// pg_trigger +// pg_sequence // // Schema: (column offset: column_name) // 0: oid (pkey) -// 1: sqdboid : database_oid -// 2: sqname : sequence_name -// 3: sqinc : seq_increment -// 4: sqmax : seq_max -// 5: sqmin : seq_min -// 6: sqstart : seq_start -// 7: sqcycle : seq_cycle -// 7: sqval : seq_value +// 1: sqdboid : database_oid +// 2: sqnamespace : namespace_oid +// 3: sqname : sequence_name +// 4: sqinc : seq_increment +// 5: sqmax : seq_max +// 6: sqmin : seq_min +// 7: sqstart : seq_start +// 8: sqcycle : seq_cycle +// 9: sqval : seq_value // // Indexes: (index offset: indexed columns) // 0: oid (primary key) -// 1: (sqdboid, sqname) (secondary key 0) +// 1: (sqdboid, sqnamespace, sqname) (secondary key 0) //===----------------------------------------------------------------------===// #pragma once @@ -40,6 +41,7 @@ #include "catalog/abstract_catalog.h" #include "catalog/catalog_defaults.h" #include "catalog/system_catalogs.h" +#include "common/internal_types.h" namespace peloton { @@ -51,13 +53,15 @@ namespace catalog { class SequenceCatalogObject { public: - SequenceCatalogObject(oid_t seqoid, oid_t dboid, const std::string &name, + SequenceCatalogObject(oid_t seqoid, oid_t dboid, oid_t namespaceoid, + const std::string &name, const int64_t seqstart, const int64_t seqincrement, const int64_t seqmax, const int64_t seqmin, const bool seqcycle, const int64_t seqval, concurrency::TransactionContext *txn) : seq_oid(seqoid), db_oid(dboid), + namespace_oid(namespaceoid), seq_name(name), seq_start(seqstart), seq_increment(seqincrement), @@ -76,6 +80,10 @@ class SequenceCatalogObject { return (db_oid); } + oid_t GetNamespaceOid() const { + return (namespace_oid); + } + std::string GetName() const { return (seq_name); } @@ -126,6 +134,7 @@ class SequenceCatalogObject { private: oid_t seq_oid; oid_t db_oid; + oid_t namespace_oid; std::string seq_name; int64_t seq_start; // Start value of the sequence int64_t seq_increment; // Increment value of the sequence @@ -152,7 +161,7 @@ class SequenceCatalog : public AbstractCatalog { /** * @brief Insert the sequence by name. - * @param database_oid the databse_oid associated with the sequence + * @param database_oid the database_oid associated with the sequence * @param sequence_name the name of the sequence * @param seq_increment the increment per step of the sequence * @param seq_max the max value of the sequence @@ -164,11 +173,14 @@ class SequenceCatalog : public AbstractCatalog { * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE otherwise. * @exception throws SequenceException if the sequence already exists. */ - bool InsertSequence(oid_t database_oid, std::string sequence_name, - int64_t seq_increment, int64_t seq_max, int64_t seq_min, - int64_t seq_start, bool seq_cycle, - type::AbstractPool *pool, - concurrency::TransactionContext *txn); + bool InsertSequence( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + std::string sequence_name, + int64_t seq_increment, int64_t seq_max, int64_t seq_min, + int64_t seq_start, bool seq_cycle, + type::AbstractPool *pool); /** * @brief Delete the sequence by name. @@ -177,20 +189,11 @@ class SequenceCatalog : public AbstractCatalog { * @param txn current transaction * @return ResultType::SUCCESS if the sequence exists, throw exception otherwise. */ - ResultType DropSequence(const std::string &database_name, - const std::string &sequence_name, - concurrency::TransactionContext *txn); - - /** - * @brief Delete the sequence by name. The sequence is guaranteed to exist. - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence - * @param txn current transaction - * @return The result of DeleteWithIndexScan. - */ - bool DeleteSequenceByName(const std::string &sequence_name, - oid_t database_oid, - concurrency::TransactionContext *txn); + ResultType DropSequence( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name); /** * @brief get sequence from pg_sequence table @@ -200,8 +203,10 @@ class SequenceCatalog : public AbstractCatalog { * @return a SequenceCatalogObject if the sequence is found, nullptr otherwise */ std::shared_ptr GetSequence( - oid_t database_oid, const std::string &sequence_name, - concurrency::TransactionContext *txn); + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name); /** * @brief get sequence oid from pg_sequence given sequence_name and database_oid @@ -210,8 +215,11 @@ class SequenceCatalog : public AbstractCatalog { * @param txn current transaction * @return the oid_t of the sequence if the sequence is found, INVALID_OI otherwise */ - oid_t GetSequenceOid(std::string sequence_name, oid_t database_oid, - concurrency::TransactionContext *txn); + oid_t GetSequenceOid( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + std::string sequence_name); /** * @brief update the next value of the sequence in the underlying storage @@ -226,76 +234,32 @@ class SequenceCatalog : public AbstractCatalog { enum ColumnId { SEQUENCE_OID = 0, - DATABSE_OID = 1, - SEQUENCE_NAME = 2, - SEQUENCE_INC = 3, - SEQUENCE_MAX = 4, - SEQUENCE_MIN = 5, - SEQUENCE_START = 6, - SEQUENCE_CYCLE = 7, - SEQUENCE_VALUE = 8 + DATABASE_OID = 1, + NAMESPACE_OID = 2, + SEQUENCE_NAME = 3, + SEQUENCE_INC = 4, + SEQUENCE_MAX = 5, + SEQUENCE_MIN = 6, + SEQUENCE_START = 7, + SEQUENCE_CYCLE = 8, + SEQUENCE_VALUE = 9 }; enum IndexId { PRIMARY_KEY = 0, - DBOID_SEQNAME_KEY = 1 + DATABASE_NAMESPACE_SEQNAME_KEY = 1 }; - void InsertCurrValCache(std::string session_namespace_, std::string sequence_name, int64_t currval){ - std::tuple key(session_namespace_, sequence_name); - size_t hash_key = key_hash(key); - sequence_currval_cache[hash_key] = currval; - namespace_hash_lists[session_namespace_].push_back(hash_key); - sequence_name_hash_lists[sequence_name].push_back(hash_key); - } - - void EvictNamespaceCurrValCache(std::string session_namespace_){ - std::vector hash_keys = namespace_hash_lists[session_namespace_]; - for (size_t hash_key : hash_keys){ - sequence_currval_cache.erase(hash_key); - } - namespace_hash_lists.erase(session_namespace_); - } - - void EvictSequenceNameCurrValCache(std::string sequence_name){ - std::vector hash_keys = sequence_name_hash_lists[sequence_name]; - for (size_t hash_key : hash_keys){ - sequence_currval_cache.erase(hash_key); - } - sequence_name_hash_lists.erase(sequence_name); - } - - bool CheckCachedCurrValExistence(std::string session_namespace_, std::string sequence_name) { - std::tuple key(session_namespace_, sequence_name); - size_t hash_key = key_hash(key); - - if (sequence_currval_cache.find(hash_key) != sequence_currval_cache.end()) - return true; - - return false; - } - - int64_t GetCachedCurrVal(std::string session_namespace_, std::string sequence_name){ - std::tuple key(session_namespace_, sequence_name); - size_t hash_key = key_hash(key); - - return sequence_currval_cache.find(hash_key)->second; - } - private: oid_t GetNextOid() { return oid_++ | SEQUENCE_OID_MASK; } - std::unordered_map sequence_currval_cache; - std::unordered_map> namespace_hash_lists; - std::unordered_map> sequence_name_hash_lists; - boost::hash> key_hash; - void ValidateSequenceArguments(int64_t seq_increment, int64_t seq_max, int64_t seq_min, int64_t seq_start) { if (seq_min > seq_max) { throw SequenceException( StringUtil::Format( - "MINVALUE (%ld) must be no greater than MAXVALUE (%ld)", seq_min, seq_max)); + "MINVALUE (%ld) must be no greater than MAXVALUE (%ld)", + seq_min, seq_max)); } if (seq_increment == 0) { @@ -306,13 +270,15 @@ class SequenceCatalog : public AbstractCatalog { if (seq_increment > 0 && seq_start < seq_min) { throw SequenceException( StringUtil::Format( - "START value (%ld) cannot be less than MINVALUE (%ld)", seq_start, seq_min)); + "START value (%ld) cannot be less than MINVALUE (%ld)", + seq_start, seq_min)); } if (seq_increment < 0 && seq_start > seq_max) { throw SequenceException( StringUtil::Format( - "START value (%ld) cannot be greater than MAXVALUE (%ld)", seq_start, seq_max)); + "START value (%ld) cannot be greater than MAXVALUE (%ld)", + seq_start, seq_max)); } }; }; From 7b13e08459d4fac189511e37ac8775bb4503e707 Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Fri, 22 Jun 2018 10:10:39 -0400 Subject: [PATCH 5/9] Sitting in a hotel next to the Frankfurt airport. Here's what I got for you: + Starting to clean up CatalogCache API + Added the ability to get SchemaCatalog objects from DatabaseCatalog I still need to think through the proper API for retrieving a Sequence from the catalog. I will format the new files next --- src/catalog/catalog_cache.cpp | 71 +++++----- src/catalog/database_catalog.cpp | 42 +++++- src/catalog/index_catalog.cpp | 8 +- src/catalog/schema_catalog.cpp | 26 +++- src/catalog/sequence_catalog.cpp | 158 +++++++++++++--------- src/catalog/table_catalog.cpp | 12 +- src/executor/create_executor.cpp | 20 ++- src/executor/drop_executor.cpp | 13 +- src/function/sequence_functions.cpp | 105 +++++++------- src/include/catalog/catalog_cache.h | 19 +-- src/include/catalog/database_catalog.h | 66 +++++++-- src/include/catalog/schema_catalog.h | 12 +- src/include/catalog/sequence_catalog.h | 117 +++++++++------- src/include/function/sequence_functions.h | 33 ++++- test/catalog/sequence_catalog_test.cpp | 12 +- 15 files changed, 457 insertions(+), 257 deletions(-) diff --git a/src/catalog/catalog_cache.cpp b/src/catalog/catalog_cache.cpp index 22cd428a89f..c3e2ffa0d53 100644 --- a/src/catalog/catalog_cache.cpp +++ b/src/catalog/catalog_cache.cpp @@ -143,48 +143,55 @@ std::shared_ptr CatalogCache::GetCachedIndexObject( bool CatalogCache::InsertSequenceObject( std::shared_ptr sequence_object) { - if (!sequence_object || sequence_object->GetSequenceOid() == INVALID_OID) { + if (sequence_object == nullptr || sequence_object->GetSequenceOid() == INVALID_OID) { return false; // invalid object } - std::pair key = std::make_pair(sequence_object->GetDatabaseOid(), - sequence_object->GetName()); - - // check if already in cache - if (sequence_objects_cache.find(key) != - sequence_objects_cache.end()) { - LOG_DEBUG("Sequence %s already exists in cache!", - sequence_object->GetName().c_str()); - return false; - } - - sequence_objects_cache.insert( - std::make_pair(key, sequence_object)); +// FIXME +// std::pair key = std::make_pair(sequence_object->GetDatabaseOid(), +// sequence_object->GetName()); +// +// // check if already in cache +// if (sequence_objects_cache.find(key) != +// sequence_objects_cache.end()) { +// LOG_DEBUG("Sequence %s already exists in cache!", +// sequence_object->GetName().c_str()); +// return false; +// } +// +// sequence_objects_cache.insert( +// std::make_pair(key, sequence_object)); return true; } -bool CatalogCache::EvictSequenceObject(const std::string & sequence_name, - oid_t database_oid) { - std::pair key = std::make_pair(database_oid, sequence_name); - auto it = sequence_objects_cache.find(key); - if (it == sequence_objects_cache.end()) { - return false; // sequence not found in cache - } - - auto sequence_object = it->second; - PELOTON_ASSERT(sequence_object); - sequence_objects_cache.erase(it); +bool CatalogCache::EvictSequenceObject( + UNUSED_ATTRIBUTE const std::string & sequence_name, + UNUSED_ATTRIBUTE oid_t database_oid) { + // FIXME +// std::pair key = std::make_pair(database_oid, sequence_name); +// auto it = sequence_objects_cache.find(key); +// if (it == sequence_objects_cache.end()) { +// return false; // sequence not found in cache +// } +// +// auto sequence_object = it->second; +// PELOTON_ASSERT(sequence_object); +// sequence_objects_cache.erase(it); return true; } std::shared_ptr CatalogCache::GetSequenceObject( - const std::string & sequence_name, oid_t database_oid) { - std::pair key = std::make_pair(database_oid, sequence_name); - auto it = sequence_objects_cache.find(key); - if (it == sequence_objects_cache.end()) { - return nullptr; - } - return it->second; + UNUSED_ATTRIBUTE oid_t database_oid, + UNUSED_ATTRIBUTE oid_t namespace_oid, + UNUSED_ATTRIBUTE const std::string &sequence_name) { + // FIXME +// std::pair key = std::make_pair(database_oid, sequence_name); +// auto it = sequence_objects_cache.find(key); +// if (it == sequence_objects_cache.end()) { +// return nullptr; +// } +// return it->second; + return nullptr; } diff --git a/src/catalog/database_catalog.cpp b/src/catalog/database_catalog.cpp index a1dfd8571c1..7a32c0cd597 100644 --- a/src/catalog/database_catalog.cpp +++ b/src/catalog/database_catalog.cpp @@ -27,19 +27,47 @@ namespace catalog { DatabaseCatalogObject::DatabaseCatalogObject( executor::LogicalTile *tile, concurrency::TransactionContext *txn) - : database_oid(tile->GetValue(0, DatabaseCatalog::ColumnId::DATABASE_OID) + : txn(txn), + database_oid(tile->GetValue(0, DatabaseCatalog::ColumnId::DATABASE_OID) .GetAs()), database_name(tile->GetValue(0, DatabaseCatalog::ColumnId::DATABASE_NAME) .ToString()), + namespace_objects_cache_(), table_objects_cache(), table_name_cache(), - valid_table_objects(false), - txn(txn) {} + valid_table_objects(false) +{ + // Nothing to see, nothing to do! +} + + +std::shared_ptr DatabaseCatalogObject::GetSchemaObject( + oid_t namespace_oid) { + + auto pg_namespace = Catalog::GetInstance() + ->GetSystemCatalogs(database_oid) + ->GetSchemaCatalog(); + auto namespace_obj = pg_namespace->GetSchemaObject(namespace_oid, txn); + + // TODO: Shouldn't I add this to my local cache? + // I am thinking no because these objects should be stored in the CatalogCache + return (namespace_obj); +} + +std::shared_ptr DatabaseCatalogObject::GetSchemaObject( + const std::string &namespace_name) { + + auto pg_namespace = Catalog::GetInstance() + ->GetSystemCatalogs(database_oid) + ->GetSchemaCatalog(); + auto namespace_obj = pg_namespace->GetSchemaObject(namespace_name, txn); + + // TODO: Shouldn't I add this to my local cache? + // I am thinking no because these objects should be stored in the CatalogCache + return (namespace_obj); +} + -/* @brief insert table catalog object into cache - * @param table_object - * @return false if table_name already exists in cache - */ bool DatabaseCatalogObject::InsertTableObject( std::shared_ptr table_object) { if (!table_object || table_object->GetTableOid() == INVALID_OID) { diff --git a/src/catalog/index_catalog.cpp b/src/catalog/index_catalog.cpp index 371543175ad..3a71ad9e94a 100644 --- a/src/catalog/index_catalog.cpp +++ b/src/catalog/index_catalog.cpp @@ -173,11 +173,11 @@ bool IndexCatalog::DeleteIndex(oid_t database_oid, oid_t index_oid, std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(index_oid).Copy()); - auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid, + auto index_object = txn->GetCatalogCache()->GetCachedIndexObject(database_oid, index_oid); if (index_object) { auto table_object = - txn->catalog_cache.GetCachedTableObject(database_oid, + txn->GetCatalogCache()->GetCachedTableObject(database_oid, index_object->GetTableOid()); table_object->EvictAllIndexObjects(); } @@ -191,7 +191,7 @@ std::shared_ptr IndexCatalog::GetIndexObject( throw CatalogException("Transaction is invalid!"); } // try get from cache - auto index_object = txn->catalog_cache.GetCachedIndexObject(database_oid, + auto index_object = txn->GetCatalogCache()->GetCachedIndexObject(database_oid, index_oid); if (index_object) { return index_object; @@ -234,7 +234,7 @@ std::shared_ptr IndexCatalog::GetIndexObject( } // try get from cache auto index_object = - txn->catalog_cache.GetCachedIndexObject(database_name, index_name, + txn->GetCatalogCache()->GetCachedIndexObject(database_name, index_name, schema_name); if (index_object) { return index_object; diff --git a/src/catalog/schema_catalog.cpp b/src/catalog/schema_catalog.cpp index 4761bb0e776..10523cdd89c 100644 --- a/src/catalog/schema_catalog.cpp +++ b/src/catalog/schema_catalog.cpp @@ -99,6 +99,31 @@ bool SchemaCatalog::DeleteSchema(const std::string &schema_name, return DeleteWithIndexScan(index_offset, values, txn); } +std::shared_ptr SchemaCatalog::GetSchemaObject( + oid_t namespace_oid, concurrency::TransactionContext *txn) { + if (txn == nullptr) { + throw CatalogException("Transaction is invalid!"); + } + + // get from pg_namespace, index scan + std::vector column_ids(all_column_ids); + oid_t index_offset = IndexId::PRIMARY_KEY; + std::vector values; + values.push_back(type::ValueFactory::GetIntegerValue(namespace_oid)); + + auto result_tiles = + GetResultWithIndexScan(column_ids, index_offset, values, txn); + + if (result_tiles->size() == 1 && (*result_tiles)[0]->GetTupleCount() == 1) { + auto schema_object = + std::make_shared((*result_tiles)[0].get(), txn); + return schema_object; + } + + // return empty object if not found + return nullptr; +} + std::shared_ptr SchemaCatalog::GetSchemaObject( const std::string &schema_name, concurrency::TransactionContext *txn) { if (txn == nullptr) { @@ -117,7 +142,6 @@ std::shared_ptr SchemaCatalog::GetSchemaObject( if (result_tiles->size() == 1 && (*result_tiles)[0]->GetTupleCount() == 1) { auto schema_object = std::make_shared((*result_tiles)[0].get(), txn); - // TODO: we don't have cache for schema object right now return schema_object; } diff --git a/src/catalog/sequence_catalog.cpp b/src/catalog/sequence_catalog.cpp index 3bf47c685a8..21e7ddbe258 100644 --- a/src/catalog/sequence_catalog.cpp +++ b/src/catalog/sequence_catalog.cpp @@ -30,55 +30,21 @@ namespace peloton { namespace catalog { -int64_t SequenceCatalogObject::GetNextVal() { - int64_t result = seq_curr_val; - seq_prev_val = result; - if (seq_increment > 0) { - // Check to see whether the nextval is out of bound - if ((seq_max >= 0 && seq_curr_val > seq_max - seq_increment) || - (seq_max < 0 && seq_curr_val + seq_increment > seq_max)) { - if (!seq_cycle) { - throw SequenceException( - StringUtil::Format( - "nextval: reached maximum value of sequence %s (%ld)", seq_name.c_str(), seq_max)); - } - seq_curr_val = seq_min; - } else - seq_curr_val += seq_increment; - } else { - // Check to see whether the nextval is out of bound - if ((seq_min < 0 && seq_curr_val < seq_min - seq_increment) || - (seq_min >= 0 && seq_curr_val + seq_increment < seq_min)) { - if (!seq_cycle) { - throw SequenceException( - StringUtil::Format( - "nextval: reached minimum value of sequence %s (%ld)", seq_name.c_str(), seq_min)); - } - seq_curr_val = seq_max; - } else - seq_curr_val += seq_increment; - } - - Catalog::GetInstance()->GetSystemCatalogs(db_oid) - ->GetSequenceCatalog() - ->UpdateNextVal(seq_oid, seq_curr_val, txn_); - return result; -} - SequenceCatalog::SequenceCatalog(const std::string &database_name, concurrency::TransactionContext *txn) : AbstractCatalog("CREATE TABLE " + database_name + "." CATALOG_SCHEMA_NAME "." SEQUENCE_CATALOG_NAME " (" - "oid INT NOT NULL PRIMARY KEY, " - "sqdboid INT NOT NULL, " - "sqname VARCHAR NOT NULL, " - "sqinc BIGINT NOT NULL, " - "sqmax BIGINT NOT NULL, " - "sqmin BIGINT NOT NULL, " - "sqstart BIGINT NOT NULL, " - "sqcycle BOOLEAN NOT NULL, " - "sqval BIGINT NOT NULL);", + "oid INT NOT NULL PRIMARY KEY, " + "sqdboid INT NOT NULL, " + "sqnamespaceoid INT NOT NULL, " + "sqname VARCHAR NOT NULL, " + "sqinc BIGINT NOT NULL, " + "sqmax BIGINT NOT NULL, " + "sqmin BIGINT NOT NULL, " + "sqstart BIGINT NOT NULL, " + "sqcycle BOOLEAN NOT NULL, " + "sqval BIGINT NOT NULL);", txn) { Catalog::GetInstance()->CreateIndex( database_name, CATALOG_SCHEMA_NAME, SEQUENCE_CATALOG_NAME, @@ -89,19 +55,21 @@ SequenceCatalog::SequenceCatalog(const std::string &database_name, SequenceCatalog::~SequenceCatalog() {} -bool SequenceCatalog::InsertSequence(oid_t database_oid, - oid_t namespace_oid, - std::string sequence_name, - int64_t seq_increment, int64_t seq_max, - int64_t seq_min, int64_t seq_start, - bool seq_cycle, type::AbstractPool *pool, - concurrency::TransactionContext *txn) { +bool SequenceCatalog::InsertSequence( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + std::string sequence_name, + int64_t seq_increment, int64_t seq_max, + int64_t seq_min, int64_t seq_start, + bool seq_cycle, + type::AbstractPool *pool) { LOG_DEBUG("Insert Sequence Database Oid: %u", database_oid); LOG_DEBUG("Insert Sequence Sequence Name: %s", sequence_name.c_str()); ValidateSequenceArguments(seq_increment, seq_max, seq_min, seq_start); - if (GetSequence(database_oid, namespace_oid, sequence_name, txn) != nullptr) { - throw SequenceException( + if (GetSequence(txn, database_oid, namespace_oid, sequence_name) != nullptr) { + throw CatalogException( StringUtil::Format("Sequence %s already exists!", sequence_name.c_str())); } @@ -127,7 +95,7 @@ bool SequenceCatalog::InsertSequence(oid_t database_oid, type::ValueFactory::GetBigIntValue(seq_start), pool); tuple->SetValue(ColumnId::SEQUENCE_CYCLE, type::ValueFactory::GetBooleanValue(seq_cycle), pool); - // When insert value, seqval = seq_start + // When insert value, seqval = seq_start_ tuple->SetValue(ColumnId::SEQUENCE_VALUE, type::ValueFactory::GetBigIntValue(seq_start), pool); @@ -149,16 +117,17 @@ ResultType SequenceCatalog::DropSequence( ->GetSequenceCatalog() ->GetSequenceOid(txn, database_oid, namespace_oid, sequence_name); if (sequence_oid == INVALID_OID) { - throw SequenceException( + throw CatalogException( StringUtil::Format("Sequence %s does not exist!", sequence_name.c_str())); } LOG_INFO("sequence %d will be deleted!", sequence_oid); - oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; + oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + values.push_back(type::ValueFactory::GetIntegerValue(namespace_oid).Copy()); values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); // TODO: Check return result @@ -169,7 +138,10 @@ ResultType SequenceCatalog::DropSequence( std::shared_ptr SequenceCatalog::GetSequence( concurrency::TransactionContext *txn, - oid_t database_oid, oid_t namespace_oid, const std::string &sequence_name) { + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name) { + // clang-format off std::vector column_ids( {ColumnId::SEQUENCE_OID, ColumnId::SEQUENCE_START, @@ -179,6 +151,7 @@ std::shared_ptr SequenceCatalog::GetSequence( ColumnId::SEQUENCE_CYCLE, ColumnId::SEQUENCE_VALUE} ); + // clang-format on oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; std::vector values; @@ -217,25 +190,78 @@ std::shared_ptr SequenceCatalog::GetSequence( return new_sequence; } -bool SequenceCatalog::UpdateNextVal(oid_t sequence_oid, int64_t nextval, - concurrency::TransactionContext *txn){ +bool SequenceCatalog::UpdateNextVal( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name, + int64_t nextval) { + + std::vector column_ids({ + ColumnId::DATABASE_OID, ColumnId::NAMESPACE_OID, ColumnId::SEQUENCE_NAME}); + oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; + std::vector scan_values; + scan_values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + scan_values.push_back(type::ValueFactory::GetIntegerValue(namespace_oid).Copy()); + scan_values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); + std::vector update_columns({SequenceCatalog::ColumnId::SEQUENCE_VALUE}); std::vector update_values; update_values.push_back(type::ValueFactory::GetBigIntValue(nextval).Copy()); - std::vector scan_values; - scan_values.push_back(type::ValueFactory::GetIntegerValue(sequence_oid).Copy()); - oid_t index_offset = SequenceCatalog::IndexId::PRIMARY_KEY; return UpdateWithIndexScan(update_columns, update_values, scan_values, index_offset, txn); } -oid_t SequenceCatalog::GetSequenceOid(std::string sequence_name, - oid_t database_oid, - concurrency::TransactionContext *txn) { +int64_t SequenceCatalogObject::GetNextVal() { + int64_t result = seq_curr_val_; + seq_prev_val_ = result; + if (seq_increment_ > 0) { + // Check to see whether the nextval is out of bound + if ((seq_max_ >= 0 && seq_curr_val_ > seq_max_ - seq_increment_) || + (seq_max_ < 0 && seq_curr_val_ + seq_increment_ > seq_max_)) { + if (!seq_cycle_) { + throw SequenceException( + StringUtil::Format( + "nextval: reached maximum value of sequence %s (%ld)", seq_name_.c_str(), seq_max_)); + } + seq_curr_val_ = seq_min_; + } else + seq_curr_val_ += seq_increment_; + } else { + // Check to see whether the nextval is out of bound + if ((seq_min_ < 0 && seq_curr_val_ < seq_min_ - seq_increment_) || + (seq_min_ >= 0 && seq_curr_val_ + seq_increment_ < seq_min_)) { + if (!seq_cycle_) { + throw SequenceException( + StringUtil::Format( + "nextval: reached minimum value of sequence %s (%ld)", seq_name_.c_str(), seq_min_)); + } + seq_curr_val_ = seq_max_; + } else + seq_curr_val_ += seq_increment_; + } + + // FIXME + // If I am already inside of a SequenceCatalogObject, why + // do I have to do another lookup to get myself? This seems like + // are doing an unnecessary second look-up? + Catalog::GetInstance()->GetSystemCatalogs(db_oid_) + ->GetSequenceCatalog() + ->UpdateNextVal(txn_, db_oid_, namespace_oid_, seq_name_, seq_curr_val_); + return result; +} + +oid_t SequenceCatalog::GetSequenceOid( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name) { + std::vector column_ids({ColumnId::SEQUENCE_OID}); - oid_t index_offset = IndexId::DBOID_SEQNAME_KEY; + oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; std::vector values; values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); + values.push_back(type::ValueFactory::GetIntegerValue(namespace_oid).Copy()); values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); // the result is a vector of executor::LogicalTile diff --git a/src/catalog/table_catalog.cpp b/src/catalog/table_catalog.cpp index cf93bbf9647..4c794f6e7a4 100644 --- a/src/catalog/table_catalog.cpp +++ b/src/catalog/table_catalog.cpp @@ -513,8 +513,8 @@ bool TableCatalog::DeleteTable(oid_t table_oid, values.push_back(type::ValueFactory::GetIntegerValue(table_oid).Copy()); // evict from cache - auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, - table_oid); + auto table_object = txn->GetCatalogCache() + ->GetCachedTableObject(database_oid, table_oid); if (table_object) { auto database_object = DatabaseCatalog::GetInstance()->GetDatabaseObject(database_oid, txn); @@ -535,8 +535,8 @@ std::shared_ptr TableCatalog::GetTableObject( throw CatalogException("Transaction is invalid!"); } // try get from cache - auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, - table_oid); + auto table_object = txn->GetCatalogCache()-> + GetCachedTableObject(database_oid, table_oid); if (table_object) return table_object; // cache miss, get from pg_table @@ -676,7 +676,7 @@ bool TableCatalog::UpdateVersionId(oid_t update_val, oid_t table_oid, type::ValueFactory::GetIntegerValue(update_val).Copy()); // get table object, then evict table object - auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, + auto table_object = txn->GetCatalogCache()->GetCachedTableObject(database_oid, table_oid); if (table_object) { auto database_object = @@ -707,7 +707,7 @@ bool TableCatalog::UpdateDefaultLayoutOid(oid_t update_val, oid_t table_oid, type::ValueFactory::GetIntegerValue(update_val).Copy()); // get table object, then evict table object - auto table_object = txn->catalog_cache.GetCachedTableObject(database_oid, + auto table_object = txn->GetCatalogCache()->GetCachedTableObject(database_oid, table_oid); if (table_object) { auto database_object = diff --git a/src/executor/create_executor.cpp b/src/executor/create_executor.cpp index 5f9ceb0471f..3abc4a19669 100644 --- a/src/executor/create_executor.cpp +++ b/src/executor/create_executor.cpp @@ -294,19 +294,29 @@ bool CreateExecutor::CreateTrigger(const planner::CreatePlan &node) { bool CreateExecutor::CreateSequence(const planner::CreatePlan &node) { auto txn = context_->GetTransaction(); std::string database_name = node.GetDatabaseName(); + std::string namespace_name = node.GetSchemaName(); std::string sequence_name = node.GetSequenceName(); auto database_object = catalog::Catalog::GetInstance()->GetDatabaseObject( database_name, txn); + PELOTON_ASSERT(database_object != nullptr); + + auto namespace_object = database_object->GetSchemaObject(namespace_name); + PELOTON_ASSERT(namespace_object != nullptr); catalog::Catalog::GetInstance() ->GetSystemCatalogs(database_object->GetDatabaseOid()) ->GetSequenceCatalog() - ->InsertSequence( - database_object->GetDatabaseOid(), sequence_name, - node.GetSequenceIncrement(), node.GetSequenceMaxValue(), - node.GetSequenceMinValue(), node.GetSequenceStart(), - node.GetSequenceCycle(), pool_.get(), txn); + ->InsertSequence(txn, + database_object->GetDatabaseOid(), + namespace_object->GetSchemaOid(), + sequence_name, + node.GetSequenceIncrement(), + node.GetSequenceMaxValue(), + node.GetSequenceMinValue(), + node.GetSequenceStart(), + node.GetSequenceCycle(), + pool_.get()); if (txn->GetResult() == ResultType::SUCCESS) { LOG_DEBUG("Creating sequence succeeded!"); diff --git a/src/executor/drop_executor.cpp b/src/executor/drop_executor.cpp index d306ee8e464..1186b2b6ef9 100644 --- a/src/executor/drop_executor.cpp +++ b/src/executor/drop_executor.cpp @@ -222,16 +222,25 @@ bool DropExecutor::DropTrigger(const planner::DropPlan &node, bool DropExecutor::DropSequence(const planner::DropPlan &node, concurrency::TransactionContext *txn) { std::string database_name = node.GetDatabaseName(); + std::string namespace_name = node.GetSchemaName(); std::string sequence_name = node.GetSequenceName(); + auto database_object = catalog::Catalog::GetInstance()->GetDatabaseObject( - database_name, txn); + database_name, txn); + PELOTON_ASSERT(database_object != nullptr); + + auto namespace_object = database_object->GetSchemaObject(namespace_name); + PELOTON_ASSERT(namespace_object != nullptr); // drop sequence ResultType result = catalog::Catalog::GetInstance() ->GetSystemCatalogs(database_object->GetDatabaseOid()) ->GetSequenceCatalog() - ->DropSequence(database_name, sequence_name, txn); + ->DropSequence(txn, + database_object->GetDatabaseOid(), + namespace_object->GetSchemaOid(), + sequence_name); txn->SetResult(result); if (txn->GetResult() == ResultType::SUCCESS) { LOG_DEBUG("Dropping sequence succeeded!"); diff --git a/src/function/sequence_functions.cpp b/src/function/sequence_functions.cpp index a6b992bf6d6..aedfcf7c972 100644 --- a/src/function/sequence_functions.cpp +++ b/src/function/sequence_functions.cpp @@ -24,13 +24,6 @@ namespace peloton { namespace function { -/* - * @brief The actual implementation to get the incremented value for the specified sequence - * @param sequence name - * @param executor context - * @return the next value for the sequence - * @exception the sequence does not exist - */ uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, const char *sequence_name) { PELOTON_ASSERT(sequence_name != nullptr); @@ -40,10 +33,11 @@ uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, auto all_databases = txn->GetCatalogCache()->GetAllDatabaseObjects(); PELOTON_ASSERT(all_databases.empty() == false); auto database_catalog = all_databases[0]; - LOG_DEBUG("Get database oid: %u", database_catalog->GetDatabaseOid()); + oid_t database_oid = database_catalog->GetDatabaseOid(); + oid_t namespace_oid = INVALID_OID; // FIXME (session namespace) auto sequence_catalog = catalog::Catalog::GetInstance() - ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) + ->GetSystemCatalogs(database_oid) ->GetSequenceCatalog(); // initialize a new transaction for incrementing sequence value @@ -53,12 +47,15 @@ uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, // evict the old cached copy of sequence // txn->GetCatalogCache()->EvictSequenceObject(sequence_name, // database_catalog->GetDatabaseOid()); - auto sequence_object = sequence_catalog - ->GetSequence(database_catalog->GetDatabaseOid(), sequence_name, mini_txn); + auto sequence_object = + sequence_catalog->GetSequence(mini_txn, + database_oid, + namespace_oid, + sequence_name); if (sequence_object != nullptr) { int64_t val = sequence_object->GetNextVal(); - int64_t curr_val = sequence_object->GetCurrVal(); + UNUSED_ATTRIBUTE int64_t curr_val = sequence_object->GetCurrVal(); // insert the new copy of sequence into cache for future currval txn->GetCatalogCache()->InsertSequenceObject(sequence_object); @@ -69,11 +66,11 @@ uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, return Nextval(ctx, sequence_name); } - catalog::Catalog::GetInstance() - ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) - ->GetSequenceCatalog() - ->InsertCurrValCache("FIXME_SCHEMA", - sequence_name, curr_val); +// catalog::Catalog::GetInstance() +// ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) +// ->GetSequenceCatalog() +// ->InsertCurrValCache("FIXME_SCHEMA", +// sequence_name, curr_val); return val; } else { throw SequenceException( @@ -81,66 +78,64 @@ uint32_t SequenceFunctions::Nextval(executor::ExecutorContext &ctx, } } -/* - * @brief The actual implementation to get the current value for the specified sequence - * @param sequence name - * @param executor context - * @return the current value of a sequence - * @exception either the sequence does not exist, or 'call nextval before currval' - */ uint32_t SequenceFunctions::Currval(executor::ExecutorContext &ctx, const char *sequence_name) { PELOTON_ASSERT(sequence_name != nullptr); concurrency::TransactionContext* txn = ctx.GetTransaction(); + // get the database oid for this transaction // HACK: Assume that there is only one database in our cache auto all_databases = txn->GetCatalogCache()->GetAllDatabaseObjects(); PELOTON_ASSERT(all_databases.empty() == false); auto database_catalog = all_databases[0]; - - // get the sequence copy from cache - auto sequence_catalog = catalog::Catalog::GetInstance() - ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) - ->GetSequenceCatalog(); - - if(sequence_catalog->CheckCachedCurrValExistence( - "FIXME_SCHEMA", std::string(sequence_name))) { - return sequence_catalog->GetCachedCurrVal( - "FIXME_SCHEMA", std::string(sequence_name)); - } else { - // get sequence from catalog - auto sequence_object = sequence_catalog - ->GetSequence(database_catalog->GetDatabaseOid(), sequence_name, txn); - if (sequence_object != nullptr) { + oid_t database_oid = database_catalog->GetDatabaseOid(); + oid_t namespace_oid = INVALID_OID; // FIXME (session namespace) + + // Check whether we already have a copy of this sequence in our + // txn's catalog cache. If so, the we always want to return its + // current value. + auto sequence_object = txn->GetCatalogCache() + ->GetSequenceObject(database_oid, + namespace_oid, + sequence_name); + + // If there was nothing in our CatalogCache, then we need to go + // get it from the system catalog. This is only to determine whether + // we want to throw a 'not found' error or not. + // + // Important: Even if the sequence exists at this point, we have to + // throw an exception to say that it is is undefined for this session. + // Only when they call nextval() on the sequence can they call + // currval()! + if (sequence_object == nullptr) { + auto sequence_catalog = catalog::Catalog::GetInstance() + ->GetSystemCatalogs(database_catalog->GetDatabaseOid()) + ->GetSequenceCatalog(); + sequence_object = + sequence_catalog->GetSequence(txn, + database_oid, + namespace_oid, + sequence_name); + if (sequence_object == nullptr) { + // sequence does not exist throw SequenceException( - StringUtil::Format("currval for sequence \"%s\" is undefined for this session", - sequence_name)); + StringUtil::Format("Sequence \"%s\" does not exist", sequence_name)); } else { - // sequence does not exist throw SequenceException( - StringUtil::Format("Sequence \"%s\" does not exist", sequence_name)); + StringUtil::Format("currval for sequence \"%s\" is not yet defined in this session", + sequence_name)); } } + PELOTON_ASSERT(sequence_object != nullptr); + return (sequence_object->GetCurrVal()); } -/* - * @brief The wrapper function to get the incremented value for the specified sequence - * @param sequence name - * @param executor context - * @return the result of executing NextVal - */ type::Value SequenceFunctions::_Nextval(const std::vector &args) { executor::ExecutorContext* ctx = (executor::ExecutorContext*)args[1].GetAs(); uint32_t ret = SequenceFunctions::Nextval(*ctx, args[0].GetAs()); return type::ValueFactory::GetIntegerValue(ret); } -/* - * @brief The wrapper function to get the current value for the specified sequence - * @param sequence name - * @param executor context - * @return the result of executing CurrVal - */ type::Value SequenceFunctions::_Currval(const std::vector &args) { executor::ExecutorContext* ctx = (executor::ExecutorContext*)args[1].GetAs(); uint32_t ret = SequenceFunctions::Currval(*ctx, args[0].GetAs()); diff --git a/src/include/catalog/catalog_cache.h b/src/include/catalog/catalog_cache.h index 56856a34a6c..38bdeaa926a 100644 --- a/src/include/catalog/catalog_cache.h +++ b/src/include/catalog/catalog_cache.h @@ -122,13 +122,16 @@ class CatalogCache { oid_t database_oid); /** - * @brief get sequence catalog object from cache - * @param sequence_name - * @param database_oid - * @return sequence catalog object; if not found return object with invalid oid + * @brief Get sequence catalog object from cache + * @param database_oid + * @param namespace_oid + * @param sequence_name + * @return sequence catalog object; if not found return object with invalid oid */ std::shared_ptr GetSequenceObject( - const std::string &sequence_name, oid_t database_oid); + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name); // cache for database catalog object std::unordered_map> @@ -137,9 +140,9 @@ class CatalogCache { database_name_cache; // cache for sequence catalog object - std::unordered_map, - std::shared_ptr> - sequence_objects_cache; +// std::unordered_map, +// std::shared_ptr> +// sequence_objects_cache; }; diff --git a/src/include/catalog/database_catalog.h b/src/include/catalog/database_catalog.h index fc94b1944bb..d406ab38ee7 100644 --- a/src/include/catalog/database_catalog.h +++ b/src/include/catalog/database_catalog.h @@ -33,11 +33,13 @@ namespace peloton { namespace catalog { +class SchemaCatalogObject; class TableCatalogObject; class IndexCatalogObject; class DatabaseCatalogObject { friend class DatabaseCatalog; + friend class SchemaCatalog; friend class TableCatalog; friend class CatalogCache; @@ -45,6 +47,21 @@ class DatabaseCatalogObject { DatabaseCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn); + + //===--------------------------------------------------------------------===// + // Schema + //===--------------------------------------------------------------------===// + + std::shared_ptr GetSchemaObject(oid_t namespace_oid); + + std::shared_ptr GetSchemaObject(const std::string &namespace_name); + + //===--------------------------------------------------------------------===// + // Tables + // FIXME: These should be moved into SchemaCatalogObject! + //===--------------------------------------------------------------------===// + + void EvictAllTableObjects(); std::shared_ptr GetTableObject(oid_t table_oid, bool cached_only = false); @@ -64,24 +81,50 @@ class DatabaseCatalogObject { std::unordered_map> GetTableObjects(bool cached_only = false); - inline oid_t GetDatabaseOid() { return database_oid; } - inline const std::string &GetDatabaseName() { return database_name; } + //===--------------------------------------------------------------------===// + // Accessors + //===--------------------------------------------------------------------===// + + oid_t GetDatabaseOid() const { + return database_oid; + } + + const std::string &GetDatabaseName() const { + return database_name; + } private: + // Pointer to its corresponding transaction + // This object is only visible during this transaction + concurrency::TransactionContext *txn; + // member variables oid_t database_oid; std::string database_name; + //===--------------------------------------------------------------------===// + // Namespaces + //===--------------------------------------------------------------------===// + + std::unordered_map> + namespace_objects_cache_; + + //===--------------------------------------------------------------------===// + // Tables + // FIXME: These should be moved into SchemaCatalogObject! + //===--------------------------------------------------------------------===// + + /** + * @brief insert table catalog object into cache + * @param table_object + * @return false if table_name already exists in cache + */ bool InsertTableObject(std::shared_ptr table_object); bool EvictTableObject(oid_t table_oid); bool EvictTableObject(const std::string &table_name, const std::string &schema_name); void SetValidTableObjects(bool valid = true) { valid_table_objects = valid; } - std::shared_ptr GetCachedIndexObject(oid_t index_oid); - std::shared_ptr GetCachedIndexObject( - const std::string &index_name, const std::string &schema_name); - // cache for table name to oid translation std::unordered_map> table_objects_cache; @@ -89,9 +132,14 @@ class DatabaseCatalogObject { table_name_cache; bool valid_table_objects; - // Pointer to its corresponding transaction - // This object is only visible during this transaction - concurrency::TransactionContext *txn; + //===--------------------------------------------------------------------===// + // Indexes + // FIXME: These should be moved into TableCatalogObject! + //===--------------------------------------------------------------------===// + + std::shared_ptr GetCachedIndexObject(oid_t index_oid); + std::shared_ptr GetCachedIndexObject( + const std::string &index_name, const std::string &schema_name); }; class DatabaseCatalog : public AbstractCatalog { diff --git a/src/include/catalog/schema_catalog.h b/src/include/catalog/schema_catalog.h index 38a3f3cbb96..c9129fb16b6 100644 --- a/src/include/catalog/schema_catalog.h +++ b/src/include/catalog/schema_catalog.h @@ -38,8 +38,12 @@ class SchemaCatalogObject { SchemaCatalogObject(executor::LogicalTile *tile, concurrency::TransactionContext *txn); - inline oid_t GetSchemaOid() { return schema_oid; } - inline const std::string &GetSchemaName() { return schema_name; } + inline oid_t GetSchemaOid() const { + return schema_oid; + } + inline const std::string &GetSchemaName() const { + return schema_name; + } private: // member variables @@ -76,6 +80,10 @@ class SchemaCatalog : public AbstractCatalog { //===--------------------------------------------------------------------===// // Read Related API //===--------------------------------------------------------------------===// + + std::shared_ptr GetSchemaObject( + oid_t namespace_oid, concurrency::TransactionContext *txn); + std::shared_ptr GetSchemaObject( const std::string &schema_name, concurrency::TransactionContext *txn); diff --git a/src/include/catalog/sequence_catalog.h b/src/include/catalog/sequence_catalog.h index b9a7d7104f6..2fc599209e4 100644 --- a/src/include/catalog/sequence_catalog.h +++ b/src/include/catalog/sequence_catalog.h @@ -21,7 +21,7 @@ // 4: sqinc : seq_increment // 5: sqmax : seq_max // 6: sqmin : seq_min -// 7: sqstart : seq_start +// 7: sqstart : seq_start_ // 8: sqcycle : seq_cycle // 9: sqval : seq_value // @@ -53,63 +53,63 @@ namespace catalog { class SequenceCatalogObject { public: - SequenceCatalogObject(oid_t seqoid, oid_t dboid, oid_t namespaceoid, + SequenceCatalogObject(oid_t seq_oid, oid_t db_oid, oid_t namespace_oid, const std::string &name, const int64_t seqstart, const int64_t seqincrement, const int64_t seqmax, const int64_t seqmin, const bool seqcycle, const int64_t seqval, concurrency::TransactionContext *txn) - : seq_oid(seqoid), - db_oid(dboid), - namespace_oid(namespaceoid), - seq_name(name), - seq_start(seqstart), - seq_increment(seqincrement), - seq_max(seqmax), - seq_min(seqmin), - seq_cycle(seqcycle), - seq_curr_val(seqval), + : seq_oid_(seq_oid), + db_oid_(db_oid), + namespace_oid_(namespace_oid), + seq_name_(name), + seq_start_(seqstart), + seq_increment_(seqincrement), + seq_max_(seqmax), + seq_min_(seqmin), + seq_cycle_(seqcycle), + seq_curr_val_(seqval), txn_(txn) {}; oid_t GetSequenceOid() const { - return (seq_oid); + return (seq_oid_); } oid_t GetDatabaseOid() const { - return (db_oid); + return (db_oid_); } oid_t GetNamespaceOid() const { - return (namespace_oid); + return (namespace_oid_); } std::string GetName() const { - return (seq_name); + return (seq_name_); } int64_t GetStart() const { - return (seq_start); + return (seq_start_); } int64_t GetIncrement() const { - return (seq_increment); + return (seq_increment_); } int64_t GetMax() const { - return (seq_max); + return (seq_max_); } int64_t GetMin() const { - return (seq_min); + return (seq_min_); } int64_t GetCacheSize() const { - return (seq_cache); + return (seq_cache_); } bool GetAllowCycle() const { - return (seq_cycle); + return (seq_cycle_); } /** @@ -120,33 +120,32 @@ class SequenceCatalogObject { int64_t GetNextVal(); int64_t GetCurrVal() const { - return seq_prev_val; + return seq_prev_val_; } protected: - void SetCycle(bool cycle) { seq_cycle = cycle; }; + void SetCycle(bool cycle) { seq_cycle_ = cycle; }; void SetCurrVal(int64_t curr_val) { - seq_curr_val = curr_val; + seq_curr_val_ = curr_val; }; // only visible for test! private: - oid_t seq_oid; - oid_t db_oid; - oid_t namespace_oid; - std::string seq_name; - int64_t seq_start; // Start value of the sequence - int64_t seq_increment; // Increment value of the sequence - int64_t seq_max; // Maximum value of the sequence - int64_t seq_min; // Minimum value of the sequence - int64_t seq_cache; // Cache size of the sequence - bool seq_cycle; // Whether the sequence cycles - int64_t seq_curr_val; + oid_t seq_oid_; + oid_t db_oid_; + oid_t namespace_oid_; + std::string seq_name_; + int64_t seq_start_; // Start value of the sequence + int64_t seq_increment_; // Increment value of the sequence + int64_t seq_max_; // Maximum value of the sequence + int64_t seq_min_; // Minimum value of the sequence + int64_t seq_cache_; // Cache size of the sequence + bool seq_cycle_; // Whether the sequence cycles + int64_t seq_curr_val_; + int64_t seq_prev_val_; concurrency::TransactionContext *txn_; - - int64_t seq_prev_val; }; class SequenceCatalog : public AbstractCatalog { @@ -161,7 +160,9 @@ class SequenceCatalog : public AbstractCatalog { /** * @brief Insert the sequence by name. - * @param database_oid the database_oid associated with the sequence + * @param txn current transaction + * @param database_oid the database_oid for the sequence + * @param namespace_oid the namespace oid for the sequence * @param sequence_name the name of the sequence * @param seq_increment the increment per step of the sequence * @param seq_max the max value of the sequence @@ -169,7 +170,6 @@ class SequenceCatalog : public AbstractCatalog { * @param seq_start the start of the sequence * @param seq_cycle whether the sequence cycles * @param pool an instance of abstract pool - * @param txn current transaction * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE otherwise. * @exception throws SequenceException if the sequence already exists. */ @@ -184,9 +184,10 @@ class SequenceCatalog : public AbstractCatalog { /** * @brief Delete the sequence by name. - * @param database_name the database name associated with the sequence - * @param sequence_name the name of the sequence * @param txn current transaction + * @param database_oid the database_oid for the sequence + * @param namespace_oid the namespace oid for the sequence + * @param sequence_name the name of the sequence * @return ResultType::SUCCESS if the sequence exists, throw exception otherwise. */ ResultType DropSequence( @@ -197,9 +198,10 @@ class SequenceCatalog : public AbstractCatalog { /** * @brief get sequence from pg_sequence table - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence * @param txn current transaction + * @param database_oid the database_oid for the sequence + * @param namespace_oid the namespace oid for the sequence + * @param sequence_name the name of the sequence * @return a SequenceCatalogObject if the sequence is found, nullptr otherwise */ std::shared_ptr GetSequence( @@ -210,27 +212,34 @@ class SequenceCatalog : public AbstractCatalog { /** * @brief get sequence oid from pg_sequence given sequence_name and database_oid - * @param database_oid the databse_oid associated with the sequence - * @param sequence_name the name of the sequence * @param txn current transaction + * @param database_oid the database_oid for the sequence + * @param namespace_oid the namespace oid for the sequence + * @param sequence_name the name of the sequence * @return the oid_t of the sequence if the sequence is found, INVALID_OI otherwise */ oid_t GetSequenceOid( concurrency::TransactionContext *txn, oid_t database_oid, oid_t namespace_oid, - std::string sequence_name); + const std::string &sequence_name); /** * @brief update the next value of the sequence in the underlying storage + * @param txn current transaction + * @param database_oid the database_oid for the sequence + * @param namespace_oid the namespace oid for the sequence * @param sequence_oid the sequence_oid of the sequence * @param nextval the nextval of the sequence - * @param txn current transaction * @return the result of the transaction * @return */ - bool UpdateNextVal(oid_t sequence_oid, int64_t nextval, - concurrency::TransactionContext *txn); + bool UpdateNextVal( + concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name, + int64_t nextval); enum ColumnId { SEQUENCE_OID = 0, @@ -253,8 +262,12 @@ class SequenceCatalog : public AbstractCatalog { private: oid_t GetNextOid() { return oid_++ | SEQUENCE_OID_MASK; } - void ValidateSequenceArguments(int64_t seq_increment, int64_t seq_max, - int64_t seq_min, int64_t seq_start) { + void ValidateSequenceArguments( + int64_t seq_increment, + int64_t seq_max, + int64_t seq_min, + int64_t seq_start) { + if (seq_min > seq_max) { throw SequenceException( StringUtil::Format( diff --git a/src/include/function/sequence_functions.h b/src/include/function/sequence_functions.h index a91faf5dffd..7eabdde8aed 100644 --- a/src/include/function/sequence_functions.h +++ b/src/include/function/sequence_functions.h @@ -26,14 +26,43 @@ namespace function { class SequenceFunctions { public: - // Nextval will return the next value of the given sequence + /** + * @brief The actual implementation to get the incremented value + * for the specified sequence. + * @param executor context + * @param sequence name + * @return the next value for the sequence + * @exception the sequence does not exist + */ static uint32_t Nextval(executor::ExecutorContext &ctx, const char *sequence_name); - // Currval will return the current value of the given sequence + /** + * @brief The actual implementation to get the current value for the + * specified sequence. + * @param sequence name + * @param executor context + * @return the current value of a sequence + * @exception either the sequence does not exist, or 'call nextval before currval' + */ static uint32_t Currval(executor::ExecutorContext &ctx, const char *sequence_name); + //===--------------------------------------------------------------------===// // Wrapper function used for AddBuiltin Functions + //===--------------------------------------------------------------------===// + + /** + * @brief The wrapper function to get the incremented value for the + * specified sequence. + * @param args {executor context, sequence name} + * @return the result of executing NextVal + */ static type::Value _Nextval(const std::vector &args); + + /** + * @brief The wrapper function to get the current value for the specified sequence + * @param args {executor context, sequence name} + * @return the result of executing CurrVal + */ static type::Value _Currval(const std::vector &args); }; diff --git a/test/catalog/sequence_catalog_test.cpp b/test/catalog/sequence_catalog_test.cpp index 8f6df5d85e5..46aaf2d4249 100644 --- a/test/catalog/sequence_catalog_test.cpp +++ b/test/catalog/sequence_catalog_test.cpp @@ -120,12 +120,12 @@ TEST_F(SequenceCatalogTests, BasicTest) { std::shared_ptr new_sequence = GetSequenceHelper(name, txn); - EXPECT_EQ(name, new_sequence->seq_name); - EXPECT_EQ(2, new_sequence->seq_increment); - EXPECT_EQ(10, new_sequence->seq_min); - EXPECT_EQ(50, new_sequence->seq_max); - EXPECT_EQ(10, new_sequence->seq_start); - EXPECT_EQ(true, new_sequence->seq_cycle); + EXPECT_EQ(name, new_sequence->GetName()); + EXPECT_EQ(2, new_sequence->GetIncrement()); + EXPECT_EQ(10, new_sequence->GetMin()); + EXPECT_EQ(50, new_sequence->GetMax()); + EXPECT_EQ(10, new_sequence->GetStart()); + EXPECT_EQ(true, new_sequence->GetAllowCycle()); EXPECT_EQ(10, new_sequence->GetNextVal()); EXPECT_EQ(10, new_sequence->GetCurrVal()); From 74777f7f54fde718c6cdb3eb5ea35f5f95806cbc Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Fri, 22 Jun 2018 10:52:02 -0400 Subject: [PATCH 6/9] Fixed formatting... I still need to think through everything. I don't know if we need to always pass around the namespace oid... --- src/catalog/sequence_catalog.cpp | 159 ++++++++++---------- src/catalog/system_catalogs.cpp | 9 -- src/include/catalog/sequence_catalog.h | 198 ++++++++++--------------- src/include/catalog/system_catalogs.h | 12 ++ test/catalog/sequence_catalog_test.cpp | 62 ++++---- 5 files changed, 199 insertions(+), 241 deletions(-) diff --git a/src/catalog/sequence_catalog.cpp b/src/catalog/sequence_catalog.cpp index 21e7ddbe258..f8345193015 100644 --- a/src/catalog/sequence_catalog.cpp +++ b/src/catalog/sequence_catalog.cpp @@ -2,49 +2,49 @@ // // Peloton // -// sequence_catalog.h +// sequence_catalog.cpp // // Identification: src/catalog/sequence_catalog.cpp // -// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// -#include - #include "catalog/sequence_catalog.h" +#include + #include "catalog/catalog.h" #include "catalog/database_catalog.h" #include "catalog/table_catalog.h" #include "common/internal_types.h" -#include "storage/data_table.h" -#include "type/value_factory.h" -#include "function/functions.h" -#include "planner/update_plan.h" -#include "executor/update_executor.h" #include "executor/executor_context.h" +#include "executor/update_executor.h" +#include "function/functions.h" #include "optimizer/optimizer.h" #include "parser/postgresparser.h" +#include "planner/update_plan.h" +#include "storage/data_table.h" +#include "type/value_factory.h" namespace peloton { namespace catalog { SequenceCatalog::SequenceCatalog(const std::string &database_name, - concurrency::TransactionContext *txn) + concurrency::TransactionContext *txn) : AbstractCatalog("CREATE TABLE " + database_name + - "." CATALOG_SCHEMA_NAME "." SEQUENCE_CATALOG_NAME - " (" - "oid INT NOT NULL PRIMARY KEY, " - "sqdboid INT NOT NULL, " - "sqnamespaceoid INT NOT NULL, " - "sqname VARCHAR NOT NULL, " - "sqinc BIGINT NOT NULL, " - "sqmax BIGINT NOT NULL, " - "sqmin BIGINT NOT NULL, " - "sqstart BIGINT NOT NULL, " - "sqcycle BOOLEAN NOT NULL, " - "sqval BIGINT NOT NULL);", + "." CATALOG_SCHEMA_NAME "." SEQUENCE_CATALOG_NAME + " (" + "oid INT NOT NULL PRIMARY KEY, " + "sqdboid INT NOT NULL, " + "sqnamespaceoid INT NOT NULL, " + "sqname VARCHAR NOT NULL, " + "sqinc BIGINT NOT NULL, " + "sqmax BIGINT NOT NULL, " + "sqmin BIGINT NOT NULL, " + "sqstart BIGINT NOT NULL, " + "sqcycle BOOLEAN NOT NULL, " + "sqval BIGINT NOT NULL);", txn) { Catalog::GetInstance()->CreateIndex( database_name, CATALOG_SCHEMA_NAME, SEQUENCE_CATALOG_NAME, @@ -54,24 +54,19 @@ SequenceCatalog::SequenceCatalog(const std::string &database_name, SequenceCatalog::~SequenceCatalog() {} - -bool SequenceCatalog::InsertSequence( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - std::string sequence_name, - int64_t seq_increment, int64_t seq_max, - int64_t seq_min, int64_t seq_start, - bool seq_cycle, - type::AbstractPool *pool) { +bool SequenceCatalog::InsertSequence(concurrency::TransactionContext *txn, + oid_t database_oid, oid_t namespace_oid, + std::string sequence_name, + int64_t seq_increment, int64_t seq_max, + int64_t seq_min, int64_t seq_start, + bool seq_cycle, type::AbstractPool *pool) { LOG_DEBUG("Insert Sequence Database Oid: %u", database_oid); LOG_DEBUG("Insert Sequence Sequence Name: %s", sequence_name.c_str()); ValidateSequenceArguments(seq_increment, seq_max, seq_min, seq_start); if (GetSequence(txn, database_oid, namespace_oid, sequence_name) != nullptr) { - throw CatalogException( - StringUtil::Format("Sequence %s already exists!", - sequence_name.c_str())); + throw CatalogException(StringUtil::Format("Sequence %s already exists!", + sequence_name.c_str())); } std::unique_ptr tuple( @@ -103,23 +98,22 @@ bool SequenceCatalog::InsertSequence( return InsertTuple(std::move(tuple), txn); } -ResultType SequenceCatalog::DropSequence( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name) { +ResultType SequenceCatalog::DropSequence(concurrency::TransactionContext *txn, + oid_t database_oid, + oid_t namespace_oid, + const std::string &sequence_name) { if (txn == nullptr) { throw CatalogException("Transaction is invalid!"); } - oid_t sequence_oid = Catalog::GetInstance() - ->GetSystemCatalogs(database_oid) - ->GetSequenceCatalog() - ->GetSequenceOid(txn, database_oid, namespace_oid, sequence_name); + oid_t sequence_oid = + Catalog::GetInstance() + ->GetSystemCatalogs(database_oid) + ->GetSequenceCatalog() + ->GetSequenceOid(txn, database_oid, namespace_oid, sequence_name); if (sequence_oid == INVALID_OID) { - throw CatalogException( - StringUtil::Format("Sequence %s does not exist!", - sequence_name.c_str())); + throw CatalogException(StringUtil::Format("Sequence %s does not exist!", + sequence_name.c_str())); } LOG_INFO("sequence %d will be deleted!", sequence_oid); @@ -137,10 +131,8 @@ ResultType SequenceCatalog::DropSequence( } std::shared_ptr SequenceCatalog::GetSequence( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name) { + concurrency::TransactionContext *txn, oid_t database_oid, + oid_t namespace_oid, const std::string &sequence_name) { // clang-format off std::vector column_ids( {ColumnId::SEQUENCE_OID, @@ -174,12 +166,10 @@ std::shared_ptr SequenceCatalog::GetSequence( PELOTON_ASSERT(result_tiles->size() == 1); size_t tuple_count = (*result_tiles)[0]->GetTupleCount(); PELOTON_ASSERT(tuple_count == 1); - (void) tuple_count; + (void)tuple_count; auto new_sequence = std::make_shared( - (*result_tiles)[0]->GetValue(0, 0).GetAs(), - database_oid, - namespace_oid, - sequence_name, + (*result_tiles)[0]->GetValue(0, 0).GetAs(), database_oid, + namespace_oid, sequence_name, (*result_tiles)[0]->GetValue(0, 1).GetAs(), (*result_tiles)[0]->GetValue(0, 2).GetAs(), (*result_tiles)[0]->GetValue(0, 3).GetAs(), @@ -190,26 +180,29 @@ std::shared_ptr SequenceCatalog::GetSequence( return new_sequence; } -bool SequenceCatalog::UpdateNextVal( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name, - int64_t nextval) { - - std::vector column_ids({ - ColumnId::DATABASE_OID, ColumnId::NAMESPACE_OID, ColumnId::SEQUENCE_NAME}); +bool SequenceCatalog::UpdateNextVal(concurrency::TransactionContext *txn, + oid_t database_oid, oid_t namespace_oid, + const std::string &sequence_name, + int64_t nextval) { + std::vector column_ids({ColumnId::DATABASE_OID, + ColumnId::NAMESPACE_OID, + ColumnId::SEQUENCE_NAME}); oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; std::vector scan_values; - scan_values.push_back(type::ValueFactory::GetIntegerValue(database_oid).Copy()); - scan_values.push_back(type::ValueFactory::GetIntegerValue(namespace_oid).Copy()); - scan_values.push_back(type::ValueFactory::GetVarcharValue(sequence_name).Copy()); - - std::vector update_columns({SequenceCatalog::ColumnId::SEQUENCE_VALUE}); + scan_values.push_back( + type::ValueFactory::GetIntegerValue(database_oid).Copy()); + scan_values.push_back( + type::ValueFactory::GetIntegerValue(namespace_oid).Copy()); + scan_values.push_back( + type::ValueFactory::GetVarcharValue(sequence_name).Copy()); + + std::vector update_columns( + {SequenceCatalog::ColumnId::SEQUENCE_VALUE}); std::vector update_values; update_values.push_back(type::ValueFactory::GetBigIntValue(nextval).Copy()); - return UpdateWithIndexScan(update_columns, update_values, scan_values, index_offset, txn); + return UpdateWithIndexScan(update_columns, update_values, scan_values, + index_offset, txn); } int64_t SequenceCatalogObject::GetNextVal() { @@ -220,9 +213,9 @@ int64_t SequenceCatalogObject::GetNextVal() { if ((seq_max_ >= 0 && seq_curr_val_ > seq_max_ - seq_increment_) || (seq_max_ < 0 && seq_curr_val_ + seq_increment_ > seq_max_)) { if (!seq_cycle_) { - throw SequenceException( - StringUtil::Format( - "nextval: reached maximum value of sequence %s (%ld)", seq_name_.c_str(), seq_max_)); + throw SequenceException(StringUtil::Format( + "nextval: reached maximum value of sequence %s (%ld)", + seq_name_.c_str(), seq_max_)); } seq_curr_val_ = seq_min_; } else @@ -232,9 +225,9 @@ int64_t SequenceCatalogObject::GetNextVal() { if ((seq_min_ < 0 && seq_curr_val_ < seq_min_ - seq_increment_) || (seq_min_ >= 0 && seq_curr_val_ + seq_increment_ < seq_min_)) { if (!seq_cycle_) { - throw SequenceException( - StringUtil::Format( - "nextval: reached minimum value of sequence %s (%ld)", seq_name_.c_str(), seq_min_)); + throw SequenceException(StringUtil::Format( + "nextval: reached minimum value of sequence %s (%ld)", + seq_name_.c_str(), seq_min_)); } seq_curr_val_ = seq_max_; } else @@ -245,18 +238,16 @@ int64_t SequenceCatalogObject::GetNextVal() { // If I am already inside of a SequenceCatalogObject, why // do I have to do another lookup to get myself? This seems like // are doing an unnecessary second look-up? - Catalog::GetInstance()->GetSystemCatalogs(db_oid_) + Catalog::GetInstance() + ->GetSystemCatalogs(db_oid_) ->GetSequenceCatalog() ->UpdateNextVal(txn_, db_oid_, namespace_oid_, seq_name_, seq_curr_val_); return result; } -oid_t SequenceCatalog::GetSequenceOid( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name) { - +oid_t SequenceCatalog::GetSequenceOid(concurrency::TransactionContext *txn, + oid_t database_oid, oid_t namespace_oid, + const std::string &sequence_name) { std::vector column_ids({ColumnId::SEQUENCE_OID}); oid_t index_offset = IndexId::DATABASE_NAMESPACE_SEQNAME_KEY; std::vector values; diff --git a/src/catalog/system_catalogs.cpp b/src/catalog/system_catalogs.cpp index dacc35f86ad..bcfd50145af 100644 --- a/src/catalog/system_catalogs.cpp +++ b/src/catalog/system_catalogs.cpp @@ -22,11 +22,6 @@ namespace peloton { namespace catalog { -/*@brief system catalog constructor, create core catalog tables and manually - * insert records into pg_attribute - * @param database the database which the catalog tables belongs to - * @param txn TransactionContext - */ SystemCatalogs::SystemCatalogs(storage::Database *database, type::AbstractPool *pool, concurrency::TransactionContext *txn) @@ -82,10 +77,6 @@ SystemCatalogs::~SystemCatalogs() { if (pg_query_metrics_) delete pg_query_metrics_; } -/*@brief using sql create statement to create secondary catalog tables - * @param database_name the database which the namespace belongs to - * @param txn TransactionContext - */ void SystemCatalogs::Bootstrap(const std::string &database_name, concurrency::TransactionContext *txn) { LOG_DEBUG("Bootstrapping database: %s", database_name.c_str()); diff --git a/src/include/catalog/sequence_catalog.h b/src/include/catalog/sequence_catalog.h index 2fc599209e4..50bb93f907d 100644 --- a/src/include/catalog/sequence_catalog.h +++ b/src/include/catalog/sequence_catalog.h @@ -6,10 +6,31 @@ // // Identification: src/include/catalog/sequence_catalog.h // -// Copyright (c) 2015-17, Carnegie Mellon University Database Group +// Copyright (c) 2015-2018, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// +#pragma once + +#include +#include +#include +#include +#include + +#include "catalog/abstract_catalog.h" +#include "catalog/catalog_defaults.h" +#include "catalog/system_catalogs.h" +#include "common/internal_types.h" + +namespace peloton { + +namespace concurrency { +class TransactionContext; +} + +namespace catalog { + //===----------------------------------------------------------------------===// // pg_sequence // @@ -30,34 +51,13 @@ // 1: (sqdboid, sqnamespace, sqname) (secondary key 0) //===----------------------------------------------------------------------===// -#pragma once - -#include -#include -#include -#include -#include - -#include "catalog/abstract_catalog.h" -#include "catalog/catalog_defaults.h" -#include "catalog/system_catalogs.h" -#include "common/internal_types.h" - -namespace peloton { - -namespace concurrency { -class TransactionContext; -} - -namespace catalog { - class SequenceCatalogObject { public: SequenceCatalogObject(oid_t seq_oid, oid_t db_oid, oid_t namespace_oid, - const std::string &name, - const int64_t seqstart, const int64_t seqincrement, - const int64_t seqmax, const int64_t seqmin, - const bool seqcycle, const int64_t seqval, + const std::string &name, const int64_t seqstart, + const int64_t seqincrement, const int64_t seqmax, + const int64_t seqmin, const bool seqcycle, + const int64_t seqval, concurrency::TransactionContext *txn) : seq_oid_(seq_oid), db_oid_(db_oid), @@ -69,62 +69,39 @@ class SequenceCatalogObject { seq_min_(seqmin), seq_cycle_(seqcycle), seq_curr_val_(seqval), - txn_(txn) {}; - + txn_(txn){}; - oid_t GetSequenceOid() const { - return (seq_oid_); - } + oid_t GetSequenceOid() const { return (seq_oid_); } - oid_t GetDatabaseOid() const { - return (db_oid_); - } + oid_t GetDatabaseOid() const { return (db_oid_); } - oid_t GetNamespaceOid() const { - return (namespace_oid_); - } + oid_t GetNamespaceOid() const { return (namespace_oid_); } - std::string GetName() const { - return (seq_name_); - } + std::string GetName() const { return (seq_name_); } - int64_t GetStart() const { - return (seq_start_); - } + int64_t GetStart() const { return (seq_start_); } - int64_t GetIncrement() const { - return (seq_increment_); - } + int64_t GetIncrement() const { return (seq_increment_); } - int64_t GetMax() const { - return (seq_max_); - } + int64_t GetMax() const { return (seq_max_); } - int64_t GetMin() const { - return (seq_min_); - } + int64_t GetMin() const { return (seq_min_); } - int64_t GetCacheSize() const { - return (seq_cache_); - } + int64_t GetCacheSize() const { return (seq_cache_); } - bool GetAllowCycle() const { - return (seq_cycle_); - } + bool GetAllowCycle() const { return (seq_cycle_); } /** * @brief Get the nextval of the sequence - * @exception throws SequenceException if the sequence exceeds the upper/lower limit + * @exception throws SequenceException if the sequence exceeds the upper/lower + * limit * @return */ int64_t GetNextVal(); - int64_t GetCurrVal() const { - return seq_prev_val_; - } + int64_t GetCurrVal() const { return (seq_prev_val_); } protected: - void SetCycle(bool cycle) { seq_cycle_ = cycle; }; void SetCurrVal(int64_t curr_val) { @@ -170,17 +147,15 @@ class SequenceCatalog : public AbstractCatalog { * @param seq_start the start of the sequence * @param seq_cycle whether the sequence cycles * @param pool an instance of abstract pool - * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE otherwise. + * @return ResultType::SUCCESS if the sequence exists, ResultType::FAILURE + * otherwise. * @exception throws SequenceException if the sequence already exists. */ - bool InsertSequence( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - std::string sequence_name, - int64_t seq_increment, int64_t seq_max, int64_t seq_min, - int64_t seq_start, bool seq_cycle, - type::AbstractPool *pool); + bool InsertSequence(concurrency::TransactionContext *txn, oid_t database_oid, + oid_t namespace_oid, std::string sequence_name, + int64_t seq_increment, int64_t seq_max, int64_t seq_min, + int64_t seq_start, bool seq_cycle, + type::AbstractPool *pool); /** * @brief Delete the sequence by name. @@ -188,13 +163,12 @@ class SequenceCatalog : public AbstractCatalog { * @param database_oid the database_oid for the sequence * @param namespace_oid the namespace oid for the sequence * @param sequence_name the name of the sequence - * @return ResultType::SUCCESS if the sequence exists, throw exception otherwise. + * @return ResultType::SUCCESS if the sequence exists, throw exception + * otherwise. */ - ResultType DropSequence( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name); + ResultType DropSequence(concurrency::TransactionContext *txn, + oid_t database_oid, oid_t namespace_oid, + const std::string &sequence_name); /** * @brief get sequence from pg_sequence table @@ -202,27 +176,25 @@ class SequenceCatalog : public AbstractCatalog { * @param database_oid the database_oid for the sequence * @param namespace_oid the namespace oid for the sequence * @param sequence_name the name of the sequence - * @return a SequenceCatalogObject if the sequence is found, nullptr otherwise + * @return a SequenceCatalogObject if the sequence is found, nullptr + * otherwise */ std::shared_ptr GetSequence( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name); + concurrency::TransactionContext *txn, oid_t database_oid, + oid_t namespace_oid, const std::string &sequence_name); /** - * @brief get sequence oid from pg_sequence given sequence_name and database_oid + * @brief get sequence oid from pg_sequence given sequence_name and + * database_oid * @param txn current transaction * @param database_oid the database_oid for the sequence * @param namespace_oid the namespace oid for the sequence * @param sequence_name the name of the sequence - * @return the oid_t of the sequence if the sequence is found, INVALID_OI otherwise + * @return the oid_t of the sequence if the sequence is found, INVALID_OI + * otherwise */ - oid_t GetSequenceOid( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name); + oid_t GetSequenceOid(concurrency::TransactionContext *txn, oid_t database_oid, + oid_t namespace_oid, const std::string &sequence_name); /** * @brief update the next value of the sequence in the underlying storage @@ -234,12 +206,9 @@ class SequenceCatalog : public AbstractCatalog { * @return the result of the transaction * @return */ - bool UpdateNextVal( - concurrency::TransactionContext *txn, - oid_t database_oid, - oid_t namespace_oid, - const std::string &sequence_name, - int64_t nextval); + bool UpdateNextVal(concurrency::TransactionContext *txn, oid_t database_oid, + oid_t namespace_oid, const std::string &sequence_name, + int64_t nextval); enum ColumnId { SEQUENCE_OID = 0, @@ -254,44 +223,33 @@ class SequenceCatalog : public AbstractCatalog { SEQUENCE_VALUE = 9 }; - enum IndexId { - PRIMARY_KEY = 0, - DATABASE_NAMESPACE_SEQNAME_KEY = 1 - }; + enum IndexId { PRIMARY_KEY = 0, DATABASE_NAMESPACE_SEQNAME_KEY = 1 }; private: oid_t GetNextOid() { return oid_++ | SEQUENCE_OID_MASK; } - void ValidateSequenceArguments( - int64_t seq_increment, - int64_t seq_max, - int64_t seq_min, - int64_t seq_start) { - + void ValidateSequenceArguments(int64_t seq_increment, int64_t seq_max, + int64_t seq_min, int64_t seq_start) { if (seq_min > seq_max) { - throw SequenceException( - StringUtil::Format( - "MINVALUE (%ld) must be no greater than MAXVALUE (%ld)", - seq_min, seq_max)); + throw SequenceException(StringUtil::Format( + "MINVALUE (%ld) must be no greater than MAXVALUE (%ld)", seq_min, + seq_max)); } if (seq_increment == 0) { - throw SequenceException( - StringUtil::Format("INCREMENT must not be zero")); + throw SequenceException(StringUtil::Format("INCREMENT must not be zero")); } if (seq_increment > 0 && seq_start < seq_min) { - throw SequenceException( - StringUtil::Format( - "START value (%ld) cannot be less than MINVALUE (%ld)", - seq_start, seq_min)); + throw SequenceException(StringUtil::Format( + "START value (%ld) cannot be less than MINVALUE (%ld)", seq_start, + seq_min)); } if (seq_increment < 0 && seq_start > seq_max) { - throw SequenceException( - StringUtil::Format( - "START value (%ld) cannot be greater than MAXVALUE (%ld)", - seq_start, seq_max)); + throw SequenceException(StringUtil::Format( + "START value (%ld) cannot be greater than MAXVALUE (%ld)", seq_start, + seq_max)); } }; }; diff --git a/src/include/catalog/system_catalogs.h b/src/include/catalog/system_catalogs.h index 0d0fbda2d04..4164c1dacc2 100644 --- a/src/include/catalog/system_catalogs.h +++ b/src/include/catalog/system_catalogs.h @@ -42,11 +42,23 @@ class SystemCatalogs { public: SystemCatalogs() = delete; + /** + * @brief system catalog constructor, create core catalog tables and manually + * insert records into pg_attribute + * @param database the database which the catalog tables belongs to + * @param pool + * @param txn TransactionContext + */ SystemCatalogs(storage::Database *database, type::AbstractPool *pool, concurrency::TransactionContext *txn); ~SystemCatalogs(); + /** + * @brief using sql create statement to create secondary catalog tables + * @param database_name the database which the namespace belongs to <- ??? + * @param txn + */ void Bootstrap(const std::string &database_name, concurrency::TransactionContext *txn); diff --git a/test/catalog/sequence_catalog_test.cpp b/test/catalog/sequence_catalog_test.cpp index 46aaf2d4249..663f17d4a33 100644 --- a/test/catalog/sequence_catalog_test.cpp +++ b/test/catalog/sequence_catalog_test.cpp @@ -37,15 +37,23 @@ class SequenceCatalogTests : public PelotonTest { std::shared_ptr GetSequenceHelper( std::string sequence_name, concurrency::TransactionContext *txn) { - // Check the effect of creation - oid_t database_oid = catalog::Catalog::GetInstance() - ->GetDatabaseWithName(DEFAULT_DB_NAME, txn) - ->GetOid(); + + // We need to have both a database + namespace at this point + auto database_obj = catalog::Catalog::GetInstance() + ->GetDatabaseObject(DEFAULT_DB_NAME, txn); + EXPECT_NE(nullptr, database_obj); + + auto namespace_obj = database_obj->GetSchemaObject(DEFAULT_SCHEMA_NAME); + EXPECT_NE(nullptr, namespace_obj); + std::shared_ptr new_sequence = catalog::Catalog::GetInstance() - ->GetSystemCatalogs(database_oid) + ->GetSystemCatalogs(database_obj->GetDatabaseOid()) ->GetSequenceCatalog() - ->GetSequence(database_oid, sequence_name, txn); + ->GetSequence(txn, + database_obj->GetDatabaseOid(), + namespace_obj->GetSchemaOid(), + sequence_name); return new_sequence; } @@ -194,18 +202,17 @@ TEST_F(SequenceCatalogTests, NextValPosIncrementFunctionalityTest) { nextVal = new_sequence->GetNextVal(); EXPECT_EQ(11, nextVal); + // FIXME // test cycle - new_sequence->SetCurrVal(50); - nextVal = new_sequence->GetNextVal(); - nextVal = new_sequence->GetNextVal(); - EXPECT_EQ(10, nextVal); - - // test no cycle - new_sequence->SetCycle(false); - new_sequence->SetCurrVal(50); - - // Expect exception - EXPECT_THROW(new_sequence->GetNextVal(), peloton::SequenceException); +// new_sequence->SetCurrVal(50); +// nextVal = new_sequence->GetNextVal(); +// nextVal = new_sequence->GetNextVal(); +// EXPECT_EQ(10, nextVal); +// +// // test no cycle +// new_sequence->SetCycle(false); +// new_sequence->SetCurrVal(50); +// EXPECT_THROW(new_sequence->GetNextVal(), peloton::SequenceException); txn_manager.CommitTransaction(txn); } @@ -231,17 +238,16 @@ TEST_F(SequenceCatalogTests, NextValNegIncrementFunctionalityTest) { nextVal = new_sequence->GetNextVal(); EXPECT_EQ(50, nextVal); - new_sequence->SetCurrVal(49); - nextVal = new_sequence->GetNextVal(); - nextVal = new_sequence->GetNextVal(); - EXPECT_EQ(48, nextVal); - - // test no cycle - new_sequence->SetCycle(false); - new_sequence->SetCurrVal(10); - - // Expect exception - EXPECT_THROW(new_sequence->GetNextVal(), peloton::SequenceException); + // FIXME +// new_sequence->SetCurrVal(49); +// nextVal = new_sequence->GetNextVal(); +// nextVal = new_sequence->GetNextVal(); +// EXPECT_EQ(48, nextVal); +// +// // test no cycle +// new_sequence->SetCycle(false); +// new_sequence->SetCurrVal(10); +// EXPECT_THROW(new_sequence->GetNextVal(), peloton::SequenceException); txn_manager.CommitTransaction(txn); } From af643d41135ffcc7f941f83a4f4ccf120e0ae86e Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Fri, 22 Jun 2018 11:31:34 -0400 Subject: [PATCH 7/9] Trying to clean up this catalog mess --- src/catalog/catalog.cpp | 20 ++++---------- src/catalog/schema_catalog.cpp | 2 +- src/include/catalog/catalog.h | 21 +++++++++++++- src/include/catalog/sequence_catalog.h | 38 +++++++++++++------------- 4 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 59fa42ce755..794478110d8 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -44,18 +44,11 @@ namespace peloton { namespace catalog { -// Get instance of the global catalog Catalog *Catalog::GetInstance() { static Catalog global_catalog; return &global_catalog; } -/* Initialization of catalog, including: - * 1) create peloton database, create catalog tables, add them into - * peloton database, insert columns into pg_attribute - * 2) create necessary indexes, insert into pg_index - * 3) insert peloton into pg_database, catalog tables into pg_table - */ Catalog::Catalog() : pool_(new type::EphemeralPool()) { // Begin transaction for catalog initialization auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); @@ -78,13 +71,6 @@ Catalog::Catalog() : pool_(new type::EphemeralPool()) { txn_manager.CommitTransaction(txn); } -/*@brief This function *MUST* be called after a new database is created to - * bootstrap all system catalog tables for that database. The system catalog - * tables must be created in certain order to make sure all tuples are indexed - * - * @param database database which this system catalogs belong to - * @param txn transaction context - */ void Catalog::BootstrapSystemCatalogs(storage::Database *database, concurrency::TransactionContext *txn) { oid_t database_oid = database->GetOid(); @@ -256,6 +242,10 @@ ResultType Catalog::CreateDatabase(const std::string &database_name, catalog_map_[database_oid]->Bootstrap(database_name, txn); LOG_TRACE("Database %s created. Returning RESULT_SUCCESS.", database_name.c_str()); + + // Then create the default namespace for our new database + // CreateSchema(database_name, DEFAULT_SCHEMA_NAME, txn); + return ResultType::SUCCESS; } @@ -283,7 +273,7 @@ ResultType Catalog::CreateSchema(const std::string &database_name, catalog_map_[database_object->GetDatabaseOid()]->GetSchemaCatalog(); auto schema_object = pg_namespace->GetSchemaObject(schema_name, txn); if (schema_object != nullptr) - throw CatalogException("Schema(namespace) " + schema_name + + throw CatalogException("Namespace " + schema_name + " already exists"); // Since there isn't physical class corresponds to schema(namespace), the only // thing needs to be done is inserting record into pg_namespace diff --git a/src/catalog/schema_catalog.cpp b/src/catalog/schema_catalog.cpp index 10523cdd89c..918662da54f 100644 --- a/src/catalog/schema_catalog.cpp +++ b/src/catalog/schema_catalog.cpp @@ -131,7 +131,7 @@ std::shared_ptr SchemaCatalog::GetSchemaObject( } // get from pg_namespace, index scan std::vector column_ids(all_column_ids); - oid_t index_offset = IndexId::SKEY_SCHEMA_NAME; // Index of database_name + oid_t index_offset = IndexId::SKEY_SCHEMA_NAME; // Index of namespace_name std::vector values; values.push_back( type::ValueFactory::GetVarcharValue(schema_name, nullptr).Copy()); diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 5b9d4fd2ba1..76e246820b9 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -78,7 +78,10 @@ struct FunctionData { class Catalog { public: - // Global Singleton + /** + * Global Singleton + * @deprecated + */ static Catalog *GetInstance(); // Bootstrap additional catalogs, only used in system initialization phase @@ -270,8 +273,24 @@ class Catalog { const std::string &name, const std::vector &argument_types); private: + + /** + * Initialization of catalog, including: + * (1) create peloton database, create catalog tables, add them into + * peloton database, insert columns into pg_attribute + * (2) create necessary indexes, insert into pg_index + * (3) insert peloton into pg_database, catalog tables into pg_table + */ Catalog(); + /** + * This function *MUST* be called after a new database is created to + * bootstrap all system catalog tables for that database. The system catalog + * tables must be created in certain order to make sure all tuples are indexed + * + * @param database database which this system catalogs belong to + * @param txn transaction context + */ void BootstrapSystemCatalogs(storage::Database *database, concurrency::TransactionContext *txn); diff --git a/src/include/catalog/sequence_catalog.h b/src/include/catalog/sequence_catalog.h index 50bb93f907d..23f240a9fd1 100644 --- a/src/include/catalog/sequence_catalog.h +++ b/src/include/catalog/sequence_catalog.h @@ -12,25 +12,6 @@ #pragma once -#include -#include -#include -#include -#include - -#include "catalog/abstract_catalog.h" -#include "catalog/catalog_defaults.h" -#include "catalog/system_catalogs.h" -#include "common/internal_types.h" - -namespace peloton { - -namespace concurrency { -class TransactionContext; -} - -namespace catalog { - //===----------------------------------------------------------------------===// // pg_sequence // @@ -51,6 +32,25 @@ namespace catalog { // 1: (sqdboid, sqnamespace, sqname) (secondary key 0) //===----------------------------------------------------------------------===// +#include +#include +#include +#include +#include + +#include "catalog/abstract_catalog.h" +#include "catalog/catalog_defaults.h" +#include "catalog/system_catalogs.h" +#include "common/internal_types.h" + +namespace peloton { + +namespace concurrency { +class TransactionContext; +} + +namespace catalog { + class SequenceCatalogObject { public: SequenceCatalogObject(oid_t seq_oid, oid_t db_oid, oid_t namespace_oid, From 19565985e73da2b98e68062878fe855c985dbb48 Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Fri, 22 Jun 2018 11:43:30 -0400 Subject: [PATCH 8/9] Trying to clean up Catalog object... --- src/catalog/catalog.cpp | 40 --------------- src/include/catalog/catalog.h | 93 +++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/src/catalog/catalog.cpp b/src/catalog/catalog.cpp index 794478110d8..7191da8e4b5 100644 --- a/src/catalog/catalog.cpp +++ b/src/catalog/catalog.cpp @@ -864,10 +864,6 @@ ResultType Catalog::DropLayout(oid_t database_oid, oid_t table_oid, // GET WITH NAME - CHECK FROM CATALOG TABLES, USING TRANSACTION //===--------------------------------------------------------------------===// -/* Check database from pg_database with database_name using txn, - * get it from storage layer using database_oid, - * throw exception and abort txn if not exists/invisible - * */ storage::Database *Catalog::GetDatabaseWithName( const std::string &database_name, concurrency::TransactionContext *txn) const { @@ -885,10 +881,6 @@ storage::Database *Catalog::GetDatabaseWithName( return storage_manager->GetDatabaseWithOid(database_object->GetDatabaseOid()); } -/* Check table from pg_table with table_name & schema_name using txn, - * get it from storage layer using table_oid, - * throw exception and abort txn if not exists/invisible - * */ storage::DataTable *Catalog::GetTableWithName( const std::string &database_name, const std::string &schema_name, const std::string &table_name, concurrency::TransactionContext *txn) { @@ -951,10 +943,6 @@ std::shared_ptr Catalog::GetDatabaseObject( return database_object; } -/* Check table from pg_table with table_name & schema_name using txn, - * get it from storage layer using table_oid, - * throw exception and abort txn if not exists/invisible - * */ std::shared_ptr Catalog::GetTableObject( const std::string &database_name, const std::string &schema_name, const std::string &table_name, concurrency::TransactionContext *txn) { @@ -1026,24 +1014,6 @@ std::shared_ptr Catalog::GetSystemCatalogs( return catalog_map_[database_oid]; } -//===--------------------------------------------------------------------===// -// DEPRECATED -//===--------------------------------------------------------------------===// - -// This should be deprecated! this can screw up the database oid system -void Catalog::AddDatabase(storage::Database *database) { - std::lock_guard lock(catalog_mutex); - auto storage_manager = storage::StorageManager::GetInstance(); - storage_manager->AddDatabaseToStorageManager(database); - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto txn = txn_manager.BeginTransaction(); - BootstrapSystemCatalogs(database, txn); - DatabaseCatalog::GetInstance()->InsertDatabase( - database->GetOid(), database->GetDBName(), pool_.get(), - txn); // I guess this can pass tests - txn_manager.CommitTransaction(txn); -} - //===--------------------------------------------------------------------===// // HELPERS //===--------------------------------------------------------------------===// @@ -1056,16 +1026,6 @@ Catalog::~Catalog() { // FUNCTION //===--------------------------------------------------------------------===// -/* @brief - * Add a new built-in function. This proceeds in two steps: - * 1. Add the function information into pg_catalog.pg_proc - * 2. Register the function pointer in function::BuiltinFunction - * @param name & argument_types function name and arg types used in SQL - * @param return_type the return type - * @param prolang the oid of which language the function is - * @param func_name the function name in C++ source (should be unique) - * @param func_ptr the pointer to the function - */ void Catalog::AddBuiltinFunction( const std::string &name, const std::vector &argument_types, const type::TypeId return_type, oid_t prolang, const std::string &func_name, diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 76e246820b9..1793ebc2866 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -192,60 +192,87 @@ class Catalog { */ ResultType DropLayout(oid_t database_oid, oid_t table_oid, oid_t layout_oid, concurrency::TransactionContext *txn); + //===--------------------------------------------------------------------===// // GET WITH NAME - CHECK FROM CATALOG TABLES, USING TRANSACTION //===--------------------------------------------------------------------===// - /* Check database from pg_database with database_name using txn, + /** + * Check database from pg_database with database_name using txn, * get it from storage layer using database_oid, * throw exception and abort txn if not exists/invisible - * */ + */ storage::Database *GetDatabaseWithName( const std::string &db_name, concurrency::TransactionContext *txn) const; - /* Check table from pg_table with table_name & schema_name using txn, - * get it from storage layer using table_oid, - * throw exception and abort txn if not exists/invisible - * */ - storage::DataTable *GetTableWithName(const std::string &database_name, - const std::string &schema_name, - const std::string &table_name, - concurrency::TransactionContext *txn); - /* Check table from pg_database with database_name using txn, - * get it from storage layer using table_oid, + /** + * Get the database catalog object from pg_database * throw exception and abort txn if not exists/invisible - * */ + * @param database_name + * @param txn + * @return + */ std::shared_ptr GetDatabaseObject( const std::string &database_name, concurrency::TransactionContext *txn); + + /** + * + * @param database_oid + * @param txn + * @return + */ std::shared_ptr GetDatabaseObject( oid_t database_oid, concurrency::TransactionContext *txn); - /* Check table from pg_table with table_name using txn, + /** + * Check table from pg_table with table_name & schema_name using txn, + * get it from storage layer using table_oid, + * throw exception and abort txn if not exists/invisible + * @param database_name + * @param schema_name + * @param table_name + * @param txn + * @return + */ + storage::DataTable *GetTableWithName(const std::string &database_name, + const std::string &schema_name, + const std::string &table_name, + concurrency::TransactionContext *txn); + + /** + * Check table from pg_table with table_name & schema_name using txn, * get it from storage layer using table_oid, * throw exception and abort txn if not exists/invisible - * */ + * @param database_name + * @param schema_name + * @param table_name + * @param txn + * @return + */ std::shared_ptr GetTableObject( const std::string &database_name, const std::string &schema_name, const std::string &table_name, concurrency::TransactionContext *txn); + + /** + * Check table from pg_table with table_name using txn, + * get it from storage layer using table_oid, + * throw exception and abort txn if not exists/invisible + * @param database_oid + * @param table_oid + * @param txn + * @return + */ std::shared_ptr GetTableObject( oid_t database_oid, oid_t table_oid, concurrency::TransactionContext *txn); - /* - * Using database oid to get system catalog object + /** + * @brief Using database oid to get system catalog object + * @param database_oid + * @return */ std::shared_ptr GetSystemCatalogs(const oid_t database_oid); - //===--------------------------------------------------------------------===// - // DEPRECATED FUNCTIONS - //===--------------------------------------------------------------------===// - /* - * We're working right now to remove metadata from storage level and eliminate - * multiple copies, so those functions below will be DEPRECATED soon. - */ - - // Add a database - void AddDatabase(storage::Database *database); //===--------------------------------------------------------------------===// // BUILTIN FUNCTION @@ -262,6 +289,18 @@ class Catalog { std::shared_ptr code_context, concurrency::TransactionContext *txn); + /** + * Add a new built-in function. This proceeds in two steps: + * 1. Add the function information into pg_catalog.pg_proc + * 2. Register the function pointer in function::BuiltinFunction + * @param name function name used in SQL + * @param argument_types arg types used in SQL + * @param return_type the return type + * @param prolang the oid of which language the function is + * @param func_name the function name in C++ source (should be unique) + * @param func the pointer to the function + * @param txn + */ void AddBuiltinFunction(const std::string &name, const std::vector &argument_types, const type::TypeId return_type, oid_t prolang, From 5c745457dbfb63315c3740548e552a6ca4f6f610 Mon Sep 17 00:00:00 2001 From: Andy Pavlo Date: Fri, 22 Jun 2018 11:50:16 -0400 Subject: [PATCH 9/9] This is one of those commits that you just dream about for years. And yet here we are! Removing the microbenchmarks! No longer will we get TPC-C numbers by running embedded logic. We will keep everything real over JDBC. I would like to give a shout out to KB for sticking with me all this time. I am sitting in a German hotel waiting for her to fly in from Pittsburgh tomorrow. --- src/include/benchmark/benchmark_common.h | 124 -- .../benchmark/logger/logger_configuration.h | 95 - .../benchmark/logger/logger_workload.h | 61 - src/include/benchmark/peloton/main.h | 32 - .../benchmark/sdbench/sdbench_configuration.h | 151 -- .../benchmark/sdbench/sdbench_loader.h | 36 - .../benchmark/sdbench/sdbench_workload.h | 29 - src/include/benchmark/tpcc/tpcc.sql | 140 -- .../benchmark/tpcc/tpcc_configuration.h | 238 --- src/include/benchmark/tpcc/tpcc_loader.h | 215 -- src/include/benchmark/tpcc/tpcc_workload.h | 58 - .../benchmark/tpch/tpch_configuration.h | 120 -- src/include/benchmark/tpch/tpch_database.h | 107 - src/include/benchmark/tpch/tpch_workload.h | 90 - .../benchmark/ycsb/ycsb_configuration.h | 129 -- src/include/benchmark/ycsb/ycsb_loader.h | 31 - src/include/benchmark/ycsb/ycsb_workload.h | 48 - src/main/logger/logger.cpp | 102 - src/main/logger/logger_configuration.cpp | 441 ----- src/main/logger/logger_workload.cpp | 421 ---- src/main/sdbench/sdbench.cpp | 72 - src/main/sdbench/sdbench_configuration.cpp | 566 ------ src/main/sdbench/sdbench_loader.cpp | 136 -- src/main/sdbench/sdbench_workload.cpp | 1545 --------------- src/main/tpcc/tpcc.cpp | 103 - src/main/tpcc/tpcc_configuration.cpp | 271 --- src/main/tpcc/tpcc_delivery.cpp | 572 ------ src/main/tpcc/tpcc_loader.cpp | 1764 ----------------- src/main/tpcc/tpcc_new_order.cpp | 732 ------- src/main/tpcc/tpcc_order_status.cpp | 354 ---- src/main/tpcc/tpcc_payment.cpp | 743 ------- src/main/tpcc/tpcc_stock_level.cpp | 273 --- src/main/tpcc/tpcc_workload.cpp | 421 ---- src/main/tpch/tpch.cpp | 125 -- src/main/tpch/tpch_configuration.cpp | 117 -- src/main/tpch/tpch_database.cpp | 690 ------- src/main/tpch/tpch_workload.cpp | 214 -- src/main/tpch/tpch_workload_q1.cpp | 170 -- src/main/tpch/tpch_workload_q3.cpp | 253 --- src/main/tpch/tpch_workload_q6.cpp | 138 -- src/main/ycsb/ycsb.cpp | 102 - src/main/ycsb/ycsb_configuration.cpp | 318 --- src/main/ycsb/ycsb_loader.cpp | 209 -- src/main/ycsb/ycsb_mixed.cpp | 231 --- src/main/ycsb/ycsb_workload.cpp | 321 --- 45 files changed, 13108 deletions(-) delete mode 100644 src/include/benchmark/benchmark_common.h delete mode 100644 src/include/benchmark/logger/logger_configuration.h delete mode 100644 src/include/benchmark/logger/logger_workload.h delete mode 100644 src/include/benchmark/peloton/main.h delete mode 100644 src/include/benchmark/sdbench/sdbench_configuration.h delete mode 100644 src/include/benchmark/sdbench/sdbench_loader.h delete mode 100644 src/include/benchmark/sdbench/sdbench_workload.h delete mode 100644 src/include/benchmark/tpcc/tpcc.sql delete mode 100644 src/include/benchmark/tpcc/tpcc_configuration.h delete mode 100644 src/include/benchmark/tpcc/tpcc_loader.h delete mode 100644 src/include/benchmark/tpcc/tpcc_workload.h delete mode 100644 src/include/benchmark/tpch/tpch_configuration.h delete mode 100644 src/include/benchmark/tpch/tpch_database.h delete mode 100644 src/include/benchmark/tpch/tpch_workload.h delete mode 100644 src/include/benchmark/ycsb/ycsb_configuration.h delete mode 100644 src/include/benchmark/ycsb/ycsb_loader.h delete mode 100644 src/include/benchmark/ycsb/ycsb_workload.h delete mode 100644 src/main/logger/logger.cpp delete mode 100644 src/main/logger/logger_configuration.cpp delete mode 100644 src/main/logger/logger_workload.cpp delete mode 100644 src/main/sdbench/sdbench.cpp delete mode 100644 src/main/sdbench/sdbench_configuration.cpp delete mode 100644 src/main/sdbench/sdbench_loader.cpp delete mode 100644 src/main/sdbench/sdbench_workload.cpp delete mode 100644 src/main/tpcc/tpcc.cpp delete mode 100644 src/main/tpcc/tpcc_configuration.cpp delete mode 100644 src/main/tpcc/tpcc_delivery.cpp delete mode 100644 src/main/tpcc/tpcc_loader.cpp delete mode 100644 src/main/tpcc/tpcc_new_order.cpp delete mode 100644 src/main/tpcc/tpcc_order_status.cpp delete mode 100644 src/main/tpcc/tpcc_payment.cpp delete mode 100644 src/main/tpcc/tpcc_stock_level.cpp delete mode 100644 src/main/tpcc/tpcc_workload.cpp delete mode 100644 src/main/tpch/tpch.cpp delete mode 100644 src/main/tpch/tpch_configuration.cpp delete mode 100644 src/main/tpch/tpch_database.cpp delete mode 100644 src/main/tpch/tpch_workload.cpp delete mode 100644 src/main/tpch/tpch_workload_q1.cpp delete mode 100644 src/main/tpch/tpch_workload_q3.cpp delete mode 100644 src/main/tpch/tpch_workload_q6.cpp delete mode 100644 src/main/ycsb/ycsb.cpp delete mode 100644 src/main/ycsb/ycsb_configuration.cpp delete mode 100644 src/main/ycsb/ycsb_loader.cpp delete mode 100644 src/main/ycsb/ycsb_mixed.cpp delete mode 100644 src/main/ycsb/ycsb_workload.cpp diff --git a/src/include/benchmark/benchmark_common.h b/src/include/benchmark/benchmark_common.h deleted file mode 100644 index 698d4a7b793..00000000000 --- a/src/include/benchmark/benchmark_common.h +++ /dev/null @@ -1,124 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_workload.h -// -// Identification: src/include/benchmark/benchmark_common.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include -#include -#include - -#include "common/platform.h" - -namespace peloton { -namespace benchmark { - -// Fast random number generator -class FastRandom { - public: - FastRandom(unsigned long seed) : seed(0) { set_seed0(seed); } - - inline unsigned long next() { - return ((unsigned long)next(32) << 32) + next(32); - } - - inline uint32_t next_u32() { return next(32); } - - inline uint16_t next_u16() { return (uint16_t)next(16); } - - /** [0.0, 1.0) */ - inline double NextUniform() { - return (((unsigned long)next(26) << 27) + next(27)) / (double)(1L << 53); - } - - inline char next_char() { return next(8) % 256; } - - inline char next_readable_char() { - static const char readables[] = - "0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; - return readables[next(6)]; - } - - inline std::string next_string(size_t len) { - std::string s(len, 0); - for (size_t i = 0; i < len; i++) s[i] = next_char(); - return s; - } - - inline std::string next_readable_string(size_t len) { - std::string s(len, 0); - for (size_t i = 0; i < len; i++) s[i] = next_readable_char(); - return s; - } - - inline unsigned long get_seed() { return seed; } - - inline void set_seed(unsigned long seed) { this->seed = seed; } - - private: - inline void set_seed0(unsigned long seed) { - this->seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1); - } - - inline unsigned long next(unsigned int bits) { - seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); - return (unsigned long)(seed >> (48 - bits)); - } - - unsigned long seed; -}; - - -class ZipfDistribution { - public: - ZipfDistribution(const uint64_t &n, const double &theta) - : rand_generator(rand()) { - // range: 1-n - the_n = n; - zipf_theta = theta; - zeta_2_theta = zeta(2, zipf_theta); - denom = zeta(the_n, zipf_theta); - } - double zeta(uint64_t n, double theta) { - double sum = 0; - for (uint64_t i = 1; i <= n; i++) sum += pow(1.0 / i, theta); - return sum; - } - int GenerateInteger(const int &min, const int &max) { - return rand_generator.next() % (max - min + 1) + min; - } - uint64_t GetNextNumber() { - double alpha = 1 / (1 - zipf_theta); - double zetan = denom; - double eta = - (1 - pow(2.0 / the_n, 1 - zipf_theta)) / (1 - zeta_2_theta / zetan); - double u = (double)(GenerateInteger(1, 10000000) % 10000000) / 10000000; - double uz = u * zetan; - if (uz < 1) return 1; - if (uz < 1 + pow(0.5, zipf_theta)) return 2; - return 1 + (uint64_t)(the_n * pow(eta * u - eta + 1, alpha)); - } - - uint64_t the_n; - double zipf_theta; - double denom; - double zeta_2_theta; - FastRandom rand_generator; -}; - -struct PadInt { - PadInt() { data = 0; } - uint64_t data; - uint32_t padding[CACHELINE_SIZE - sizeof(uint64_t)]; -}; - -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/logger/logger_configuration.h b/src/include/benchmark/logger/logger_configuration.h deleted file mode 100644 index 31cc1018919..00000000000 --- a/src/include/benchmark/logger/logger_configuration.h +++ /dev/null @@ -1,95 +0,0 @@ -// //===----------------------------------------------------------------------===// -// // -// // Peloton -// // -// // logger_configuration.h -// // -// // Identification: src/include/benchmark/logger/logger_configuration.h -// // -// // Copyright (c) 2015-16, Carnegie Mellon University Database Group -// // -// //===----------------------------------------------------------------------===// - - -// #pragma once - -// #include -// #include -// #include -// #include -// #include - -// #include "type/types.h" - -// namespace peloton { -// namespace benchmark { -// namespace logger { - -// enum ExperimentType { -// EXPERIMENT_TYPE_INVALID = 0, - -// EXPERIMENT_TYPE_THROUGHPUT = 1, -// EXPERIMENT_TYPE_RECOVERY = 2, -// EXPERIMENT_TYPE_STORAGE = 3, -// EXPERIMENT_TYPE_LATENCY = 4 -// }; - -// enum BenchmarkType { -// BENCHMARK_TYPE_INVALID = 0, - -// BENCHMARK_TYPE_YCSB = 1, -// BENCHMARK_TYPE_TPCC = 2 -// }; - -// enum AsynchronousType { -// ASYNCHRONOUS_TYPE_INVALID = 0, - -// ASYNCHRONOUS_TYPE_SYNC = 1, // logging enabled + sync commits -// ASYNCHRONOUS_TYPE_ASYNC = 2, // logging enabled + async commits -// ASYNCHRONOUS_TYPE_DISABLED = 3, // logging disabled -// ASYNCHRONOUS_TYPE_NO_WRITE = 4 -// }; - -// class configuration { -// public: -// // experiment type -// ExperimentType experiment_type; - -// // logging type -// LoggingType logging_type; - -// // checkpoint type -// CheckpointType checkpoint_type; - -// // log file dir -// std::string log_file_dir; - -// // size of the pmem file (in MB) -// size_t data_file_size; - -// // frequency with which the logger flushes -// int wait_timeout; - -// // Benchmark type -// BenchmarkType benchmark_type; - -// // clflush or clwb -// int flush_mode; - -// // nvm latency -// int nvm_latency; - -// // pcommit latency -// int pcommit_latency; - -// // asynchronous_mode -// AsynchronousType asynchronous_mode; -// }; - -// void Usage(FILE *out); - -// void ParseArguments(int argc, char *argv[], configuration &state); - -// } // namespace logger -// } // namespace benchmark -// } // namespace peloton diff --git a/src/include/benchmark/logger/logger_workload.h b/src/include/benchmark/logger/logger_workload.h deleted file mode 100644 index 3f148d37d25..00000000000 --- a/src/include/benchmark/logger/logger_workload.h +++ /dev/null @@ -1,61 +0,0 @@ -// //===----------------------------------------------------------------------===// -// // -// // Peloton -// // -// // logger_workload.h -// // -// // Identification: src/include/benchmark/logger/logger_workload.h -// // -// // Copyright (c) 2015-16, Carnegie Mellon University Database Group -// // -// //===----------------------------------------------------------------------===// - - -// #pragma once - -// #include - -// #include "benchmark/logger/logger_configuration.h" - -// namespace peloton { - -// namespace catalog { -// class Column; -// class Schema; -// } - -// namespace storage { -// class Tuple; -// class DataTable; -// } - -// namespace benchmark { -// namespace logger { - -// extern configuration state; - -// //===--------------------------------------------------------------------===// -// // PREPARE LOG FILE -// //===--------------------------------------------------------------------===// - -// bool SetupLoggingOnFollower(); - -// bool PrepareLogFile(); - -// //===--------------------------------------------------------------------===// -// // CHECK RECOVERY -// //===--------------------------------------------------------------------===// - -// void ResetSystem(void); - -// void DoRecovery(); - -// //===--------------------------------------------------------------------===// -// // WRITING LOG RECORD -// //===--------------------------------------------------------------------===// - -// void BuildLog(); - -// } // namespace logger -// } // namespace benchmark -// } // namespace peloton diff --git a/src/include/benchmark/peloton/main.h b/src/include/benchmark/peloton/main.h deleted file mode 100644 index f3df65d550c..00000000000 --- a/src/include/benchmark/peloton/main.h +++ /dev/null @@ -1,32 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// main.h -// -// Identification: src/include/benchmark/peloton/main.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include -#include -#include - -/*! - \brief Peloton DBMS namespace. - */ -namespace peloton { - -class configuration { - public: - std::string filesystem_path; -}; - -// sample test helper -int SampleFunc(int a, int b) { return a + b; } -} diff --git a/src/include/benchmark/sdbench/sdbench_configuration.h b/src/include/benchmark/sdbench/sdbench_configuration.h deleted file mode 100644 index 52edf622749..00000000000 --- a/src/include/benchmark/sdbench/sdbench_configuration.h +++ /dev/null @@ -1,151 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench_configuration.h -// -// Identification: src/include/benchmark/sdbench/sdbench_configuration.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include -#include -#include -#include -#include - -#include "storage/data_table.h" - -namespace peloton { -namespace benchmark { -namespace sdbench { - -enum IndexUsageType { - INDEX_USAGE_TYPE_INVALID = 0, - - INDEX_USAGE_TYPE_PARTIAL_FAST = 1, // use partially materialized indexes (fast) - INDEX_USAGE_TYPE_PARTIAL_MEDIUM = 2, // use partially materialized indexes (medium) - INDEX_USAGE_TYPE_PARTIAL_SLOW = 3, // use partially materialized indexes (slow) - INDEX_USAGE_TYPE_FULL = 4, // use only fully materialized indexes - INDEX_USAGE_TYPE_NEVER = 5, // never use ad-hoc indexes -}; - -enum QueryComplexityType { - QUERY_COMPLEXITY_TYPE_INVALID = 0, - - QUERY_COMPLEXITY_TYPE_SIMPLE = 1, - QUERY_COMPLEXITY_TYPE_MODERATE = 2, - QUERY_COMPLEXITY_TYPE_COMPLEX = 3 - -}; - -enum WriteComplexityType { - WRITE_COMPLEXITY_TYPE_INVALID = 0, - - WRITE_COMPLEXITY_TYPE_SIMPLE = 1, - WRITE_COMPLEXITY_TYPE_COMPLEX = 2, - // This is a special complexity type, where we do insert instead of update. - WRITE_COMPLEXITY_TYPE_INSERT = 3 -}; - -extern int orig_scale_factor; - -static const int generator_seed = 50; - -class configuration { - public: - // What kind of indexes can be used ? - IndexUsageType index_usage_type; - - // Complexity of the query. - QueryComplexityType query_complexity_type; - - // Complexity of update. - WriteComplexityType write_complexity_type; - - // size of the table - int scale_factor; - - int tuples_per_tilegroup; - - // tile group layout - LayoutType layout_mode; - - double selectivity; - - double projectivity; - - // column count - oid_t attribute_count; - - // write ratio - double write_ratio; - - // # of times to run operator - std::size_t phase_length; - - // total number of ops - size_t total_ops; - - // Verbose output - bool verbose; - - // Convergence test? - bool convergence; - - // INDEX TUNER PARAMETERS - - // duration between pauses - oid_t duration_between_pauses; - - // duration of pause - oid_t duration_of_pause; - - // sample count threshold after which - // tuner analyze iteration takes place - oid_t analyze_sample_count_threshold; - - // max tile groups indexed per tuning iteration per table - oid_t tile_groups_indexed_per_iteration; - - // CONVERGENCE PARAMETER - - // number of queries for which index configuration must remain stable - oid_t convergence_op_threshold; - - // VARIABILITY PARAMETER - oid_t variability_threshold; - - // DROP PARAMETER - - // index utility threshold - double index_utility_threshold; - - // maximum # of indexes per table - oid_t index_count_threshold; - - // write intensive workload ratio threshold - double write_ratio_threshold; - - // wether run multi stage experiment or not. - bool multi_stage; - - // whether in holistic indexing mode or not. - bool holistic_indexing; - - oid_t multi_stage_idx = 0; -}; - -void Usage(FILE *out); - -void ParseArguments(int argc, char *argv[], configuration &state); - -void GenerateSequence(oid_t column_count); - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/sdbench/sdbench_loader.h b/src/include/benchmark/sdbench/sdbench_loader.h deleted file mode 100644 index 26b4f2ed8d1..00000000000 --- a/src/include/benchmark/sdbench/sdbench_loader.h +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench_loader.h -// -// Identification: src/include/benchmark/sdbench/sdbench_loader.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include "benchmark/sdbench/sdbench_configuration.h" - -namespace peloton { -namespace benchmark { -namespace sdbench { - -extern configuration state; - -extern std::unique_ptr sdbench_table; - -void CreateTable(peloton::LayoutType layout_type); - -void LoadTable(); - -void CreateAndLoadTable(LayoutType layout_type); - -void DropIndexes(); - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/sdbench/sdbench_workload.h b/src/include/benchmark/sdbench/sdbench_workload.h deleted file mode 100644 index 3d63dc75581..00000000000 --- a/src/include/benchmark/sdbench/sdbench_workload.h +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench_workload.h -// -// Identification: src/include/benchmark/sdbench/sdbench_workload.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include "benchmark/sdbench/sdbench_configuration.h" - -namespace peloton { -namespace benchmark { -namespace sdbench { - -extern configuration state; - -void RunSDBenchTest(); -void RunMultiStageBenchmark(); - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/tpcc/tpcc.sql b/src/include/benchmark/tpcc/tpcc.sql deleted file mode 100644 index 42f6dc2887d..00000000000 --- a/src/include/benchmark/tpcc/tpcc.sql +++ /dev/null @@ -1,140 +0,0 @@ -CREATE TABLE WAREHOUSE ( - W_ID SMALLINT DEFAULT '0' NOT NULL, - W_NAME VARCHAR(16) DEFAULT NULL, - W_STREET_1 VARCHAR(32) DEFAULT NULL, - W_STREET_2 VARCHAR(32) DEFAULT NULL, - W_CITY VARCHAR(32) DEFAULT NULL, - W_STATE VARCHAR(2) DEFAULT NULL, - W_ZIP VARCHAR(9) DEFAULT NULL, - W_TAX FLOAT DEFAULT NULL, - W_YTD FLOAT DEFAULT NULL, - CONSTRAINT W_PK_ARRAY PRIMARY KEY (W_ID) -); - -CREATE TABLE DISTRICT ( - D_ID TINYINT DEFAULT '0' NOT NULL, - D_W_ID SMALLINT DEFAULT '0' NOT NULL REFERENCES WAREHOUSE (W_ID), - D_NAME VARCHAR(16) DEFAULT NULL, - D_STREET_1 VARCHAR(32) DEFAULT NULL, - D_STREET_2 VARCHAR(32) DEFAULT NULL, - D_CITY VARCHAR(32) DEFAULT NULL, - D_STATE VARCHAR(2) DEFAULT NULL, - D_ZIP VARCHAR(9) DEFAULT NULL, - D_TAX FLOAT DEFAULT NULL, - D_YTD FLOAT DEFAULT NULL, - D_NEXT_O_ID INT DEFAULT NULL, - PRIMARY KEY (D_W_ID,D_ID) -); - -CREATE TABLE ITEM ( - I_ID INTEGER DEFAULT '0' NOT NULL, - I_IM_ID INTEGER DEFAULT NULL, - I_NAME VARCHAR(32) DEFAULT NULL, - I_PRICE FLOAT DEFAULT NULL, - I_DATA VARCHAR(64) DEFAULT NULL, - CONSTRAINT I_PK_ARRAY PRIMARY KEY (I_ID) -); - -CREATE TABLE CUSTOMER ( - C_ID INTEGER DEFAULT '0' NOT NULL, - C_D_ID TINYINT DEFAULT '0' NOT NULL, - C_W_ID SMALLINT DEFAULT '0' NOT NULL, - C_FIRST VARCHAR(32) DEFAULT NULL, - C_MIDDLE VARCHAR(2) DEFAULT NULL, - C_LAST VARCHAR(32) DEFAULT NULL, - C_STREET_1 VARCHAR(32) DEFAULT NULL, - C_STREET_2 VARCHAR(32) DEFAULT NULL, - C_CITY VARCHAR(32) DEFAULT NULL, - C_STATE VARCHAR(2) DEFAULT NULL, - C_ZIP VARCHAR(9) DEFAULT NULL, - C_PHONE VARCHAR(32) DEFAULT NULL, - C_SINCE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - C_CREDIT VARCHAR(2) DEFAULT NULL, - C_CREDIT_LIM FLOAT DEFAULT NULL, - C_DISCOUNT FLOAT DEFAULT NULL, - C_BALANCE FLOAT DEFAULT NULL, - C_YTD_PAYMENT FLOAT DEFAULT NULL, - C_PAYMENT_CNT INTEGER DEFAULT NULL, - C_DELIVERY_CNT INTEGER DEFAULT NULL, - C_DATA VARCHAR(500), - PRIMARY KEY (C_W_ID,C_D_ID,C_ID), - UNIQUE (C_W_ID,C_D_ID,C_LAST,C_FIRST), - CONSTRAINT C_FKEY_D FOREIGN KEY (C_D_ID, C_W_ID) REFERENCES DISTRICT (D_ID, D_W_ID) -); -CREATE INDEX IDX_CUSTOMER ON CUSTOMER (C_W_ID,C_D_ID,C_LAST); - -CREATE TABLE HISTORY ( - H_C_ID INTEGER DEFAULT NULL, - H_C_D_ID TINYINT DEFAULT NULL, - H_C_W_ID SMALLINT DEFAULT NULL, - H_D_ID TINYINT DEFAULT NULL, - H_W_ID SMALLINT DEFAULT '0' NOT NULL, - H_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - H_AMOUNT FLOAT DEFAULT NULL, - H_DATA VARCHAR(32) DEFAULT NULL, - CONSTRAINT H_FKEY_C FOREIGN KEY (H_C_ID, H_C_D_ID, H_C_W_ID) REFERENCES CUSTOMER (C_ID, C_D_ID, C_W_ID), - CONSTRAINT H_FKEY_D FOREIGN KEY (H_D_ID, H_W_ID) REFERENCES DISTRICT (D_ID, D_W_ID) -); - -CREATE TABLE STOCK ( - S_I_ID INTEGER DEFAULT '0' NOT NULL REFERENCES ITEM (I_ID), - S_W_ID SMALLINT DEFAULT '0 ' NOT NULL REFERENCES WAREHOUSE (W_ID), - S_QUANTITY INTEGER DEFAULT '0' NOT NULL, - S_DIST_01 VARCHAR(32) DEFAULT NULL, - S_DIST_02 VARCHAR(32) DEFAULT NULL, - S_DIST_03 VARCHAR(32) DEFAULT NULL, - S_DIST_04 VARCHAR(32) DEFAULT NULL, - S_DIST_05 VARCHAR(32) DEFAULT NULL, - S_DIST_06 VARCHAR(32) DEFAULT NULL, - S_DIST_07 VARCHAR(32) DEFAULT NULL, - S_DIST_08 VARCHAR(32) DEFAULT NULL, - S_DIST_09 VARCHAR(32) DEFAULT NULL, - S_DIST_10 VARCHAR(32) DEFAULT NULL, - S_YTD INTEGER DEFAULT NULL, - S_ORDER_CNT INTEGER DEFAULT NULL, - S_REMOTE_CNT INTEGER DEFAULT NULL, - S_DATA VARCHAR(64) DEFAULT NULL, - PRIMARY KEY (S_W_ID,S_I_ID) -); - -CREATE TABLE ORDERS ( - O_ID INTEGER DEFAULT '0' NOT NULL, - O_C_ID INTEGER DEFAULT NULL, - O_D_ID TINYINT DEFAULT '0' NOT NULL, - O_W_ID SMALLINT DEFAULT '0' NOT NULL, - O_ENTRY_D TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - O_CARRIER_ID INTEGER DEFAULT NULL, - O_OL_CNT INTEGER DEFAULT NULL, - O_ALL_LOCAL INTEGER DEFAULT NULL, - PRIMARY KEY (O_W_ID,O_D_ID,O_ID), - UNIQUE (O_W_ID,O_D_ID,O_C_ID,O_ID), - CONSTRAINT O_FKEY_C FOREIGN KEY (O_C_ID, O_D_ID, O_W_ID) REFERENCES CUSTOMER (C_ID, C_D_ID, C_W_ID) -); -CREATE INDEX IDX_ORDERS ON ORDERS (O_W_ID,O_D_ID,O_C_ID); - -CREATE TABLE NEW_ORDER ( - NO_O_ID INTEGER DEFAULT '0' NOT NULL, - NO_D_ID TINYINT DEFAULT '0' NOT NULL, - NO_W_ID SMALLINT DEFAULT '0' NOT NULL, - CONSTRAINT NO_PK_TREE PRIMARY KEY (NO_D_ID,NO_W_ID,NO_O_ID), - CONSTRAINT NO_FKEY_O FOREIGN KEY (NO_O_ID, NO_D_ID, NO_W_ID) REFERENCES ORDERS (O_ID, O_D_ID, O_W_ID) -); - -CREATE TABLE ORDER_LINE ( - OL_O_ID INTEGER DEFAULT '0' NOT NULL, - OL_D_ID TINYINT DEFAULT '0' NOT NULL, - OL_W_ID SMALLINT DEFAULT '0' NOT NULL, - OL_NUMBER INTEGER DEFAULT '0' NOT NULL, - OL_I_ID INTEGER DEFAULT NULL, - OL_SUPPLY_W_ID SMALLINT DEFAULT NULL, - OL_DELIVERY_D TIMESTAMP DEFAULT NULL, - OL_QUANTITY INTEGER DEFAULT NULL, - OL_AMOUNT FLOAT DEFAULT NULL, - OL_DIST_INFO VARCHAR(32) DEFAULT NULL, - PRIMARY KEY (OL_W_ID,OL_D_ID,OL_O_ID,OL_NUMBER), - CONSTRAINT OL_FKEY_O FOREIGN KEY (OL_O_ID, OL_D_ID, OL_W_ID) REFERENCES ORDERS (O_ID, O_D_ID, O_W_ID), - CONSTRAINT OL_FKEY_S FOREIGN KEY (OL_I_ID, OL_SUPPLY_W_ID) REFERENCES STOCK (S_I_ID, S_W_ID) -); ---CREATE INDEX IDX_ORDER_LINE_3COL ON ORDER_LINE (OL_W_ID,OL_D_ID,OL_O_ID); ---CREATE INDEX IDX_ORDER_LINE_2COL ON ORDER_LINE (OL_W_ID,OL_D_ID); -CREATE INDEX IDX_ORDER_LINE_TREE ON ORDER_LINE (OL_W_ID,OL_D_ID,OL_O_ID); diff --git a/src/include/benchmark/tpcc/tpcc_configuration.h b/src/include/benchmark/tpcc/tpcc_configuration.h deleted file mode 100644 index c46a8333b41..00000000000 --- a/src/include/benchmark/tpcc/tpcc_configuration.h +++ /dev/null @@ -1,238 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_configuration.h -// -// Identification: src/include/benchmark/tpcc/tpcc_configuration.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "common/internal_types.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -static const oid_t tpcc_database_oid = 100; - -static const oid_t warehouse_table_oid = 1001; -static const oid_t warehouse_table_pkey_index_oid = 20010; // W_ID - -static const oid_t district_table_oid = 1002; -static const oid_t district_table_pkey_index_oid = 20021; // D_ID, D_W_ID - -static const oid_t item_table_oid = 1003; -static const oid_t item_table_pkey_index_oid = 20030; // I_ID - -static const oid_t customer_table_oid = 1004; -static const oid_t customer_table_pkey_index_oid = - 20040; // C_W_ID, C_D_ID, C_ID -static const oid_t customer_table_skey_index_oid = - 20041; // C_W_ID, C_D_ID, C_LAST - -static const oid_t history_table_oid = 1005; - -static const oid_t stock_table_oid = 1006; -static const oid_t stock_table_pkey_index_oid = 20060; // S_W_ID, S_I_ID - -static const oid_t orders_table_oid = 1007; -static const oid_t orders_table_pkey_index_oid = 20070; // O_W_ID, O_D_ID, O_ID -static const oid_t orders_table_skey_index_oid = - 20071; // O_W_ID, O_D_ID, O_C_ID - -static const oid_t new_order_table_oid = 1008; -static const oid_t new_order_table_pkey_index_oid = - 20080; // NO_D_ID, NO_W_ID, NO_O_ID - -static const oid_t order_line_table_oid = 1008; -static const oid_t order_line_table_pkey_index_oid = - 20080; // OL_W_ID, OL_D_ID, OL_O_ID, OL_NUMBER -static const oid_t order_line_table_skey_index_oid = - 20081; // OL_W_ID, OL_D_ID, OL_O_ID - -//=========== -// Column ids -//=========== - -// NEW_ORDER -#define COL_IDX_NO_O_ID 0 -#define COL_IDX_NO_D_ID 1 -#define COL_IDX_NO_W_ID 2 - -// ORDERS -#define COL_IDX_O_ID 0 -#define COL_IDX_O_C_ID 1 -#define COL_IDX_O_D_ID 2 -#define COL_IDX_O_W_ID 3 -#define COL_IDX_O_ENTRY_D 4 -#define COL_IDX_O_CARRIER_ID 5 -#define COL_IDX_O_OL_CNT 6 -#define COL_IDX_O_ALL_LOCAL 7 - -// ORDER_LINE -#define COL_IDX_OL_O_ID 0 -#define COL_IDX_OL_D_ID 1 -#define COL_IDX_OL_W_ID 2 -#define COL_IDX_OL_NUMBER 3 -#define COL_IDX_OL_I_ID 4 -#define COL_IDX_OL_SUPPLY_W_ID 5 -#define COL_IDX_OL_DELIVERY_D 6 -#define COL_IDX_OL_QUANTITY 7 -#define COL_IDX_OL_AMOUNT 8 -#define COL_IDX_OL_DIST_INFO 9 - -// Customer -#define COL_IDX_C_ID 0 -#define COL_IDX_C_D_ID 1 -#define COL_IDX_C_W_ID 2 -#define COL_IDX_C_FIRST 3 -#define COL_IDX_C_MIDDLE 4 -#define COL_IDX_C_LAST 5 -#define COL_IDX_C_STREET_1 6 -#define COL_IDX_C_STREET_2 7 -#define COL_IDX_C_CITY 8 -#define COL_IDX_C_STATE 9 -#define COL_IDX_C_ZIP 10 -#define COL_IDX_C_PHONE 11 -#define COL_IDX_C_SINCE 12 -#define COL_IDX_C_CREDIT 13 -#define COL_IDX_C_CREDIT_LIM 14 -#define COL_IDX_C_DISCOUNT 15 -#define COL_IDX_C_BALANCE 16 -#define COL_IDX_C_YTD_PAYMENT 17 -#define COL_IDX_C_PAYMENT_CNT 18 -#define COL_IDX_C_DELIVERY_CNT 19 -#define COL_IDX_C_DATA 20 - -// District -#define COL_IDX_D_ID 0 -#define COL_IDX_D_W_ID 1 -#define COL_IDX_D_NAME 2 -#define COL_IDX_D_STREET_1 3 -#define COL_IDX_D_STREET_2 4 -#define COL_IDX_D_CITY 5 -#define COL_IDX_D_STATE 6 -#define COL_IDX_D_ZIP 7 -#define COL_IDX_D_TAX 8 -#define COL_IDX_D_YTD 9 -#define COL_IDX_D_NEXT_O_ID 10 - -// Stock -#define COL_IDX_S_I_ID 0 -#define COL_IDX_S_W_ID 1 -#define COL_IDX_S_QUANTITY 2 -#define COL_IDX_S_DIST_01 3 -#define COL_IDX_S_DIST_02 4 -#define COL_IDX_S_DIST_03 5 -#define COL_IDX_S_DIST_04 6 -#define COL_IDX_S_DIST_05 7 -#define COL_IDX_S_DIST_06 8 -#define COL_IDX_S_DIST_07 9 -#define COL_IDX_S_DIST_08 10 -#define COL_IDX_S_DIST_09 11 -#define COL_IDX_S_DIST_10 12 -#define COL_IDX_S_YTD 13 -#define COL_IDX_S_ORDER_CNT 14 -#define COL_IDX_S_REMOTE_CNT 15 -#define COL_IDX_S_DATA 16 - - -class configuration { - public: - - // index type - IndexType index; - - // epoch type - EpochType epoch; - - // scale factor - double scale_factor; - - // execution duration (in s) - double duration; - - // profile duration (in s) - double profile_duration; - - // number of backends - int backend_count; - - // num of warehouses - int warehouse_count; - - // item count - int item_count; - - int districts_per_warehouse; - - int customers_per_district; - - int new_orders_per_district; - - // exponential backoff - bool exp_backoff; - - // client affinity - bool affinity; - - // garbage collection - bool gc_mode; - - // number of gc threads - bool gc_backend_count; - - // number of loaders - int loader_count; - - // throughput - double throughput = 0; - - // abort rate - double abort_rate = 0; - - std::vector profile_throughput; - - std::vector profile_abort_rate; - - std::vector profile_memory; - -}; - -extern configuration state; - -void Usage(FILE *out); - -void ParseArguments(int argc, char *argv[], configuration &state); - -void ValidateIndex(const configuration &state); - -void ValidateScaleFactor(const configuration &state); - -void ValidateDuration(const configuration &state); - -void ValidateProfileDuration(const configuration &state); - -void ValidateBackendCount(const configuration &state); - -void ValidateWarehouseCount(const configuration &state); - -void ValidateGCBackendCount(const configuration &state); - -void WriteOutput(); - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/tpcc/tpcc_loader.h b/src/include/benchmark/tpcc/tpcc_loader.h deleted file mode 100644 index 91f6e14e56c..00000000000 --- a/src/include/benchmark/tpcc/tpcc_loader.h +++ /dev/null @@ -1,215 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_loader.h -// -// Identification: src/include/benchmark/tpcc/tpcc_loader.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include - -#include "benchmark/tpcc/tpcc_configuration.h" - -namespace peloton { -namespace storage { -class Database; -class DataTable; -class Tuple; -} - -class VarlenPool; - -namespace benchmark { -namespace tpcc { - -extern configuration state; - -void CreateTPCCDatabase(); - -void LoadTPCCDatabase(); - -///////////////////////////////////////////////////////// -// Tables -///////////////////////////////////////////////////////// - -extern storage::Database* tpcc_database; - -extern storage::DataTable* warehouse_table; -extern storage::DataTable* district_table; -extern storage::DataTable* item_table; -extern storage::DataTable* customer_table; -extern storage::DataTable* history_table; -extern storage::DataTable* stock_table; -extern storage::DataTable* orders_table; -extern storage::DataTable* new_order_table; -extern storage::DataTable* order_line_table; - -///////////////////////////////////////////////////////// -// Constants -///////////////////////////////////////////////////////// - -extern const size_t name_length; -extern const size_t middle_name_length; -extern const size_t data_length; -extern const size_t state_length; -extern const size_t zip_length; -extern const size_t street_length; -extern const size_t city_length; -extern const size_t credit_length; -extern const size_t phone_length; -extern const size_t dist_length; - -extern double item_min_price; -extern double item_max_price; - -extern double warehouse_name_length; -extern double warehouse_min_tax; -extern double warehouse_max_tax; -extern double warehouse_initial_ytd; - -extern double district_name_length; -extern double district_min_tax; -extern double district_max_tax; -extern double district_initial_ytd; - -extern std::string customers_good_credit; -extern std::string customers_bad_credit; -extern double customers_bad_credit_ratio; -extern double customers_init_credit_lim; -extern double customers_min_discount; -extern double customers_max_discount; -extern double customers_init_balance; -extern double customers_init_ytd; -extern int customers_init_payment_cnt; -extern int customers_init_delivery_cnt; - -extern double history_init_amount; -extern size_t history_data_length; - -extern int orders_min_ol_cnt; -extern int orders_max_ol_cnt; -extern int orders_init_all_local; -extern int orders_null_carrier_id; -extern int orders_min_carrier_id; -extern int orders_max_carrier_id; - -extern int new_orders_per_district; - -extern int order_line_init_quantity; -extern int order_line_max_ol_quantity; -extern double order_line_min_amount; -extern size_t order_line_dist_info_length; - -extern double stock_original_ratio; -extern int stock_min_quantity; -extern int stock_max_quantity; -extern int stock_dist_count; - -extern double payment_min_amount; -extern double payment_max_amount; - -extern int stock_min_threshold; -extern int stock_max_threshold; - -extern double new_order_remote_txns; - -extern const int syllable_count; -extern const char* syllables[]; - -extern const std::string data_constant; - -struct NURandConstant { - int c_last; - int c_id; - int order_line_itme_id; - - NURandConstant(); -}; - -extern NURandConstant nu_rand_const; - -///////////////////////////////////////////////////////// -// Tuple Constructors -///////////////////////////////////////////////////////// - -std::unique_ptr BuildItemTuple( - const int item_id, const std::unique_ptr& pool); - -std::unique_ptr BuildWarehouseTuple( - const int warehouse_id, const std::unique_ptr& pool); - -std::unique_ptr BuildDistrictTuple( - const int district_id, const int warehouse_id, - const std::unique_ptr& pool); - -std::unique_ptr BuildCustomerTuple( - const int customer_id, const int district_id, const int warehouse_id, - const std::unique_ptr& pool); - -std::unique_ptr BuildHistoryTuple( - const int customer_id, const int district_id, const int warehouse_id, - const int history_district_id, const int history_warehouse_id, - const std::unique_ptr& pool); - -std::unique_ptr BuildOrdersTuple(const int orders_id, - const int district_id, - const int warehouse_id, - const bool new_order, - const int o_ol_cnt); - -std::unique_ptr BuildNewOrderTuple(const int orders_id, - const int district_id, - const int warehouse_id); - -std::unique_ptr BuildOrderLineTuple( - const int orders_id, const int district_id, const int warehouse_id, - const int order_line_id, const int ol_supply_w_id, const bool new_order, - const std::unique_ptr& pool); - -std::unique_ptr BuildStockTuple( - const int stock_id, const int s_w_id, - const std::unique_ptr& pool); - -///////////////////////////////////////////////////////// -// Utils -///////////////////////////////////////////////////////// - -std::string GetRandomAlphaNumericString(const size_t string_length); - -int GetNURand(int a, int x, int y); - -std::string GetLastName(int number); - -std::string GetRandomLastName(int max_cid); - -bool GetRandomBoolean(double ratio); - -int GetRandomInteger(const int lower_bound, const int upper_bound); - -int GetRandomIntegerExcluding(const int lower_bound, const int upper_bound, - const int exclude_sample); - -double GetRandomDouble(const double lower_bound, const double upper_bound); - -double GetRandomFixedPoint(int decimal_places, double minimum, double maximum); - -std::string GetStreetName(); - -std::string GetZipCode(); - -std::string GetCityName(); - -std::string GetStateName(); - -int GetTimeStamp(); - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/tpcc/tpcc_workload.h b/src/include/benchmark/tpcc/tpcc_workload.h deleted file mode 100644 index 7978f00f395..00000000000 --- a/src/include/benchmark/tpcc/tpcc_workload.h +++ /dev/null @@ -1,58 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_workload.h -// -// Identification: src/include/benchmark/tpcc/tpcc_workload.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include "common/macros.h" -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "executor/abstract_executor.h" - -namespace peloton { - -namespace storage { -class DataTable; -} - -namespace benchmark { -namespace tpcc { - -extern configuration state; - -void RunWorkload(); - -bool RunNewOrder(const size_t &thread_id); - -bool RunPayment(const size_t &thread_id); - -bool RunDelivery(const size_t &thread_id); - -bool RunOrderStatus(const size_t &thread_id); - -bool RunStockLevel(const size_t &thread_id); - -size_t GenerateWarehouseId(const size_t &thread_id); - -///////////////////////////////////////////////////////// - -std::vector> ExecuteRead(executor::AbstractExecutor* executor); - -void ExecuteUpdate(executor::AbstractExecutor* executor); - -void ExecuteDelete(executor::AbstractExecutor* executor); - -void PinToCore(size_t core); - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/tpch/tpch_configuration.h b/src/include/benchmark/tpch/tpch_configuration.h deleted file mode 100644 index 037f65b473a..00000000000 --- a/src/include/benchmark/tpch/tpch_configuration.h +++ /dev/null @@ -1,120 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_configuration.h -// -// Identification: src/include/benchmark/tpch/tpch_configuration.h -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include -#include -#include - -#include "common/internal_types.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -//===----------------------------------------------------------------------===// -// Type size constants -//===----------------------------------------------------------------------===// - -extern oid_t kIntSize; -extern oid_t kDateSize; -extern oid_t kBigIntSize; -extern oid_t kDecimalSize; - -//===----------------------------------------------------------------------===// -// Query and Table types -//===----------------------------------------------------------------------===// - -enum class QueryId : uint32_t { - Q1 = 0, - Q2, - Q3, - Q4, - Q5, - Q6, - Q7, - Q8, - Q9, - Q10, - Q11, - Q12, - Q13, - Q14, - Q15, - Q16, - Q17, - Q18, - Q19, - Q20, - Q21, - Q22, -}; - -enum class TableId : uint32_t { - Part = 44, - Supplier = 45, - PartSupp = 46, - Customer = 47, - Nation = 48, - Lineitem = 49, - Region = 50, - Orders = 51, -}; - -//===----------------------------------------------------------------------===// -// The benchmark configuration -//===----------------------------------------------------------------------===// - -struct Configuration { - // Default 64K tuples per tile group - uint32_t tuples_per_tile_group = 1 << 16; - - // The scale factor of the benchmark - double scale_factor = 1; - - // The number of runs to average over - uint32_t num_runs = 10; - - // The directory where all the data files are - std::string data_dir; - - // The suffix of all the files - std::string suffix; - - // Do we dictionary encode strings? - bool dictionary_encode = true; - - // Which queries will the benchmark run? - bool queries_to_run[22] = {false}; - - bool IsValid() const; - - std::string GetInputPath(std::string file_name) const; - - std::string GetCustomerPath() const; - std::string GetLineitemPath() const; - std::string GetNationPath() const; - std::string GetOrdersPath() const; - std::string GetPartSuppPath() const; - std::string GetPartPath() const; - std::string GetSupplierPath() const; - std::string GetRegionPath() const; - - void SetRunnableQueries(char *query_list); - - bool ShouldRunQuery(QueryId qid) const; -}; - -} // namespace tpch -} // namespace benchmark -} // namespace pelton \ No newline at end of file diff --git a/src/include/benchmark/tpch/tpch_database.h b/src/include/benchmark/tpch/tpch_database.h deleted file mode 100644 index 34b198bff7a..00000000000 --- a/src/include/benchmark/tpch/tpch_database.h +++ /dev/null @@ -1,107 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_database.h -// -// Identification: src/include/benchmark/tpch/tpch_database.h -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include -#include - -#include "benchmark/tpch/tpch_configuration.h" - -namespace peloton { - -namespace storage { -class Database; -class DataTable; -} // namespace storage - -namespace benchmark { -namespace tpch { - -//===----------------------------------------------------------------------===// -// The TPCH Database. This class is responsible for access to all table in the -// DB. Tables are created on instantiation. Individual tables can be loaded -// from files based on the benchmark configuration parameters. Loading supports -// dictionary encoding string values. -//===----------------------------------------------------------------------===// -class TPCHDatabase { - public: - typedef std::unordered_map Dictionary; - - TPCHDatabase(const Configuration &c); - - ~TPCHDatabase(); - - storage::Database &GetDatabase() const; - - // Table accessors - storage::DataTable &GetTable(TableId table_id) const; - - // Create all tables - void CreateTables() const; - - void LoadTable(TableId table_id); - - // Load individual tables - void LoadCustomerTable(); - void LoadLineitemTable(); - void LoadNationTable(); - void LoadOrdersTable(); - void LoadPartTable(); - void LoadPartSupplierTable(); - void LoadRegionTable(); - void LoadSupplierTable(); - - uint32_t CodeForMktSegment(const std::string mktsegment) const; - - private: - uint32_t DictionaryEncode(Dictionary &dict, const std::string &val); - - // Table creators - void CreateCustomerTable() const; - void CreateLineitemTable() const; - void CreateNationTable() const; - void CreateOrdersTable() const; - void CreatePartTable() const; - void CreatePartSupplierTable() const; - void CreateRegionTable() const; - void CreateSupplierTable() const; - - // Has the given table been loaded already? - bool TableIsLoaded(TableId table_id) const { - return loaded_tables_[static_cast(table_id) - - static_cast(TableId::Part)]; - } - - void SetTableIsLoaded(TableId table_id) { - loaded_tables_[static_cast(table_id) - - static_cast(TableId::Part)] = true; - } - - private: - // The configuration - const Configuration &config_; - - // Track which tables have been loaded - bool loaded_tables_[8]; - - // Dictionary codes - Dictionary l_shipinstruct_dict_; - Dictionary l_shipmode_dict_; - Dictionary p_brand_dict_; - Dictionary p_container_dict_; - Dictionary c_mktsegment_dict_; -}; - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/include/benchmark/tpch/tpch_workload.h b/src/include/benchmark/tpch/tpch_workload.h deleted file mode 100644 index 65e1bc148b2..00000000000 --- a/src/include/benchmark/tpch/tpch_workload.h +++ /dev/null @@ -1,90 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_workload.h -// -// Identification: src/include/benchmark/tpch/tpch_workload.h -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include "benchmark/tpch/tpch_configuration.h" -#include "benchmark/tpch/tpch_database.h" - -#include "codegen/compilation_context.h" -#include "codegen/execution_consumer.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -// The benchmark -class TPCHBenchmark { - public: - TPCHBenchmark(const Configuration &config, TPCHDatabase &db); - - // Run the benchmark - void RunBenchmark(); - - private: - - struct QueryConfig { - public: - // The name of the query - std::string query_name; - - // The ID of the query - QueryId query_id; - - // The list of tables this query uses - std::vector required_tables; - - // A function that constructs a plan for this query - std::function()> PlanConstructor; - }; - - // Run the given query - void RunQuery(const QueryConfig &query_config); - - // Plan constructors - std::unique_ptr ConstructQ1Plan() const; - std::unique_ptr ConstructQ2Plan() const; - std::unique_ptr ConstructQ3Plan() const; - std::unique_ptr ConstructQ4Plan() const; - std::unique_ptr ConstructQ5Plan() const; - std::unique_ptr ConstructQ6Plan() const; - std::unique_ptr ConstructQ7Plan() const; - std::unique_ptr ConstructQ8Plan() const; - std::unique_ptr ConstructQ9Plan() const; - std::unique_ptr ConstructQ10Plan() const; - std::unique_ptr ConstructQ11Plan() const; - std::unique_ptr ConstructQ12Plan() const; - std::unique_ptr ConstructQ13Plan() const; - std::unique_ptr ConstructQ14Plan() const; - std::unique_ptr ConstructQ15Plan() const; - std::unique_ptr ConstructQ16Plan() const; - std::unique_ptr ConstructQ17Plan() const; - std::unique_ptr ConstructQ18Plan() const; - std::unique_ptr ConstructQ19Plan() const; - std::unique_ptr ConstructQ20Plan() const; - std::unique_ptr ConstructQ21Plan() const; - std::unique_ptr ConstructQ22Plan() const; - - private: - // The benchmark configuration - const Configuration &config_; - - // The TPCH database - TPCHDatabase &db_; - - // All query configurations - std::vector query_configs_; -}; - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/include/benchmark/ycsb/ycsb_configuration.h b/src/include/benchmark/ycsb/ycsb_configuration.h deleted file mode 100644 index 633dba6ddca..00000000000 --- a/src/include/benchmark/ycsb/ycsb_configuration.h +++ /dev/null @@ -1,129 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_configuration.h -// -// Identification: src/include/benchmark/ycsb/ycsb_configuration.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "common/internal_types.h" - -namespace peloton { -namespace benchmark { -namespace ycsb { - -static const oid_t ycsb_database_oid = 100; - -static const oid_t user_table_oid = 1001; - -static const oid_t user_table_pkey_index_oid = 2001; - -static const oid_t ycsb_field_length = 100; - -class configuration { - public: - - // index type - IndexType index; - - // epoch type - EpochType epoch; - - // size of the table - int scale_factor; - - // execution duration (in s) - double duration; - - // profile duration (in s) - double profile_duration; - - // number of backends - int backend_count; - - // column count - int column_count; - - // operation count in a transaction - int operation_count; - - // update ratio - double update_ratio; - - // contention level - double zipf_theta; - - // exponential backoff - bool exp_backoff; - - // store strings - bool string_mode; - - // garbage collection - bool gc_mode; - - // number of gc threads - int gc_backend_count; - - // number of loaders - int loader_count; - - // throughput - double throughput = 0; - - // abort rate - double abort_rate = 0; - - std::vector profile_throughput; - - std::vector profile_abort_rate; - - std::vector profile_memory; - -}; - -extern configuration state; - -void Usage(FILE *out); - -void ParseArguments(int argc, char *argv[], configuration &state); - -void ValidateIndex(const configuration &state); - -void ValidateScaleFactor(const configuration &state); - -void ValidateDuration(const configuration &state); - -void ValidateProfileDuration(const configuration &state); - -void ValidateBackendCount(const configuration &state); - -void ValidateColumnCount(const configuration &state); - -void ValidateOperationCount(const configuration &state); - -void ValidateUpdateRatio(const configuration &state); - -void ValidateZipfTheta(const configuration &state); - -void ValidateGCBackendCount(const configuration &state); - -void WriteOutput(); - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/ycsb/ycsb_loader.h b/src/include/benchmark/ycsb/ycsb_loader.h deleted file mode 100644 index de39ed49bd8..00000000000 --- a/src/include/benchmark/ycsb/ycsb_loader.h +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_loader.h -// -// Identification: src/include/benchmark/ycsb/ycsb_loader.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include "benchmark/ycsb/ycsb_configuration.h" - -namespace peloton { -namespace benchmark { -namespace ycsb { - -extern configuration state; - -void CreateYCSBDatabase(); - -void LoadYCSBDatabase(); -void LoadYCSBRows(const int begin_rowid, const int end_rowid); - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton diff --git a/src/include/benchmark/ycsb/ycsb_workload.h b/src/include/benchmark/ycsb/ycsb_workload.h deleted file mode 100644 index 678a5d1b81c..00000000000 --- a/src/include/benchmark/ycsb/ycsb_workload.h +++ /dev/null @@ -1,48 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_workload.h -// -// Identification: src/include/benchmark/ycsb/ycsb_workload.h -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#pragma once - -#include "benchmark/benchmark_common.h" -#include "benchmark/ycsb/ycsb_configuration.h" -#include "storage/data_table.h" -#include "executor/abstract_executor.h" - -namespace peloton { - -namespace storage { -class DataTable; -} - -namespace benchmark { -namespace ycsb { - -extern configuration state; - -extern storage::DataTable* user_table; - -void RunWorkload(); - -bool RunMixed(const size_t thread_id, ZipfDistribution &zipf, FastRandom &rng); - -///////////////////////////////////////////////////////// - -std::vector> ExecuteRead(executor::AbstractExecutor* executor); - -void ExecuteUpdate(executor::AbstractExecutor* executor); - -void PinToCore(size_t core); - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton diff --git a/src/main/logger/logger.cpp b/src/main/logger/logger.cpp deleted file mode 100644 index aaca3ff2bbe..00000000000 --- a/src/main/logger/logger.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// //===----------------------------------------------------------------------===// -// // -// // Peloton -// // -// // logger.cpp -// // -// // Identification: src/main/logger/logger.cpp -// // -// // Copyright (c) 2015-16, Carnegie Mellon University Database Group -// // -// //===----------------------------------------------------------------------===// - -// #include -// #include -// #include - -// #include "benchmark/logger/logger_configuration.h" -// #include "benchmark/logger/logger_workload.h" -// #include "benchmark/tpcc/tpcc_configuration.h" -// #include "benchmark/ycsb/ycsb_configuration.h" - -// #include "common/logger.h" -// #include "logging/logging_util.h" - -// // Logging mode -// extern peloton::LoggingType peloton_logging_mode; - -// extern peloton::CheckpointType peloton_checkpoint_mode; - -// extern size_t peloton_data_file_size; - -// extern int64_t peloton_wait_timeout; - -// // Flush mode (for NVM WBL) -// extern int peloton_flush_mode; - -// // PCOMMIT latency (for NVM WBL) -// extern int peloton_pcommit_latency; - -// namespace peloton { -// namespace benchmark { - -// namespace ycsb { -// configuration state; -// void CreateYCSBDatabase(); -// } -// namespace tpcc { -// configuration state; -// } - -// namespace logger { - -// void StartLogging(std::thread &thread); - -// // Configuration -// configuration state; - -// // Main Entry Point -// void RunBenchmark() { -// // First, set the global peloton logging mode and pmem file size -// peloton_logging_mode = state.logging_type; -// peloton_data_file_size = state.data_file_size; -// peloton_wait_timeout = state.wait_timeout; -// peloton_flush_mode = state.flush_mode; -// peloton_pcommit_latency = state.pcommit_latency; - -// //===--------------------------------------------------------------------===// -// // WAL -// //===--------------------------------------------------------------------===// -// if (logging::LoggingUtil::IsBasedOnWriteAheadLogging(peloton_logging_mode)) { -// // Prepare a simple log file -// PrepareLogFile(); - -// // Do recovery -// DoRecovery(); -// } -// //===--------------------------------------------------------------------===// -// // WBL -// //===--------------------------------------------------------------------===// -// else if (logging::LoggingUtil::IsBasedOnWriteBehindLogging(peloton_logging_mode)) { -// LOG_ERROR("currently, we do not support write behind logging."); -// PELOTON_ASSERT(false); -// // Test a simple log process -// PrepareLogFile(); - -// // Do recovery -// DoRecovery(); -// } -// } - -// } // namespace logger -// } // namespace benchmark -// } // namespace peloton - -// int main(int argc, char **argv) { -// peloton::benchmark::logger::ParseArguments(argc, argv, -// peloton::benchmark::logger::state); - -// peloton::benchmark::logger::RunBenchmark(); - -// return 0; -// } diff --git a/src/main/logger/logger_configuration.cpp b/src/main/logger/logger_configuration.cpp deleted file mode 100644 index 747cb0cc698..00000000000 --- a/src/main/logger/logger_configuration.cpp +++ /dev/null @@ -1,441 +0,0 @@ -// //===----------------------------------------------------------------------===// -// // -// // Peloton -// // -// // logger_configuration.cpp -// // -// // Identification: src/main/logger/logger_configuration.cpp -// // -// // Copyright (c) 2015-16, Carnegie Mellon University Database Group -// // -// //===----------------------------------------------------------------------===// - - -// #include -// #include -// #include - -// #include "common/exception.h" -// #include "common/logger.h" -// #include "storage/storage_manager.h" - -// #include "benchmark/logger/logger_configuration.h" -// #include "benchmark/ycsb/ycsb_configuration.h" -// #include "benchmark/tpcc/tpcc_configuration.h" - -// extern peloton::CheckpointType peloton_checkpoint_mode; - -// namespace peloton { -// namespace benchmark { -// namespace logger { - -// void Usage(FILE* out) { -// fprintf(out, -// "Command line options : logger \n" -// " -h --help : Print help message \n" -// " -s --asynchronous-mode : Asynchronous mode \n" -// " -x --experiment-type : Experiment Type \n" -// " -f --data-file-size : Data file size (MB) \n" -// " -l --logging-type : Logging type \n" -// " -t --nvm-latency : NVM latency \n" -// " -q --pcommit-latency : pcommit latency \n" -// " -v --flush-mode : Flush mode \n" -// " -r --commit-interval : Group commit interval \n" -// " -j --log-dir : Log directory\n" -// " -y --benchmark-type : Benchmark type \n"); -// } - -// static struct option opts[] = { -// {"asynchronous_mode", optional_argument, NULL, 's'}, -// {"experiment-type", optional_argument, NULL, 'x'}, -// {"data-file-size", optional_argument, NULL, 'f'}, -// {"logging-type", optional_argument, NULL, 'l'}, -// {"nvm-latency", optional_argument, NULL, 't'}, -// {"pcommit-latency", optional_argument, NULL, 'q'}, -// {"flush-mode", optional_argument, NULL, 'v'}, -// {"commit-interval", optional_argument, NULL, 'r'}, -// {"benchmark-type", optional_argument, NULL, 'y'}, -// {"log-dir", optional_argument, NULL, 'j'}, -// {NULL, 0, NULL, 0}}; - -// static void ValidateLoggingType(const configuration& state) { -// if (state.logging_type <= LoggingTypeId::INVALID) { -// LOG_ERROR("Invalid logging_type :: %d", static_cast(state.logging_type)); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("Logging_type :: %s", -// LoggingTypeToString(state.logging_type).c_str()); -// } - -// std::string BenchmarkTypeToString(BenchmarkType type) { -// switch (type) { -// case BENCHMARK_TYPE_INVALID: -// return "INVALID"; - -// case BENCHMARK_TYPE_YCSB: -// return "YCSB"; -// case BENCHMARK_TYPE_TPCC: -// return "TPCC"; - -// default: -// LOG_ERROR("Invalid benchmark_type :: %d", type); -// exit(EXIT_FAILURE); -// } -// return "INVALID"; -// } - -// std::string ExperimentTypeToString(ExperimentType type) { -// switch (type) { -// case EXPERIMENT_TYPE_INVALID: -// return "INVALID"; - -// case EXPERIMENT_TYPE_THROUGHPUT: -// return "THROUGHPUT"; -// case EXPERIMENT_TYPE_RECOVERY: -// return "RECOVERY"; -// case EXPERIMENT_TYPE_STORAGE: -// return "STORAGE"; -// case EXPERIMENT_TYPE_LATENCY: -// return "LATENCY"; - -// default: -// LOG_ERROR("Invalid experiment_type :: %d", type); -// exit(EXIT_FAILURE); -// } - -// return "INVALID"; -// } - -// std::string AsynchronousTypeToString(AsynchronousType type) { -// switch (type) { -// case ASYNCHRONOUS_TYPE_INVALID: -// return "INVALID"; - -// case ASYNCHRONOUS_TYPE_SYNC: -// return "SYNC"; -// case ASYNCHRONOUS_TYPE_ASYNC: -// return "ASYNC"; -// case ASYNCHRONOUS_TYPE_DISABLED: -// return "DISABLED"; -// case ASYNCHRONOUS_TYPE_NO_WRITE: -// return "NO_WRITE"; - -// default: -// LOG_ERROR("Invalid asynchronous_mode :: %d", type); -// exit(EXIT_FAILURE); -// } - -// return "INVALID"; -// } - -// static void ValidateBenchmarkType(const configuration& state) { -// if (state.benchmark_type <= 0 || state.benchmark_type > 3) { -// LOG_ERROR("Invalid benchmark_type :: %d", state.benchmark_type); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("%s : %s", "benchmark_type", -// BenchmarkTypeToString(state.benchmark_type).c_str()); -// } - -// static void ValidateDataFileSize(const configuration& state) { -// if (state.data_file_size <= 0) { -// LOG_ERROR("Invalid data_file_size :: %lu", state.data_file_size); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("data_file_size :: %lu", state.data_file_size); -// } - -// static void ValidateExperimentType(const configuration& state) { -// if (state.experiment_type < 0 || state.experiment_type > 4) { -// LOG_ERROR("Invalid experiment_type :: %d", state.experiment_type); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("%s : %s", "experiment_type", -// ExperimentTypeToString(state.experiment_type).c_str()); -// } - -// static void ValidateWaitTimeout(const configuration& state) { -// if (state.wait_timeout < 0) { -// LOG_ERROR("Invalid wait_timeout :: %d", state.wait_timeout); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("wait_timeout :: %d", state.wait_timeout); -// } - -// static void ValidateFlushMode(const configuration& state) { -// if (state.flush_mode <= 0 || state.flush_mode >= 3) { -// LOG_ERROR("Invalid flush_mode :: %d", state.flush_mode); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("flush_mode :: %d", state.flush_mode); -// } - -// static void ValidateAsynchronousMode(const configuration& state) { -// if (state.asynchronous_mode <= ASYNCHRONOUS_TYPE_INVALID || -// state.asynchronous_mode > ASYNCHRONOUS_TYPE_NO_WRITE) { -// LOG_ERROR("Invalid asynchronous_mode :: %d", state.asynchronous_mode); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("%s : %s", "asynchronous_mode", -// AsynchronousTypeToString(state.asynchronous_mode).c_str()); -// } - -// static void ValidateNVMLatency(const configuration& state) { -// if (state.nvm_latency < 0) { -// LOG_ERROR("Invalid nvm_latency :: %d", state.nvm_latency); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("nvm_latency :: %d", state.nvm_latency); -// } - -// static void ValidatePCOMMITLatency(const configuration& state) { -// if (state.pcommit_latency < 0) { -// LOG_ERROR("Invalid pcommit_latency :: %d", state.pcommit_latency); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("pcommit_latency :: %d", state.pcommit_latency); -// } - -// static void ValidateLogFileDir(configuration& state) { -// struct stat data_stat; -// // Check the existence of the log directory -// if (stat(state.log_file_dir.c_str(), &data_stat) != 0) { -// LOG_ERROR("log_file_dir :: %s does not exist", state.log_file_dir.c_str()); -// exit(EXIT_FAILURE); -// } else if (!(data_stat.st_mode & S_IFDIR)) { -// LOG_ERROR("log_file_dir :: %s is not a directory", state.log_file_dir.c_str()); -// exit(EXIT_FAILURE); -// } - -// LOG_INFO("log_file_dir :: %s", state.log_file_dir.c_str()); -// } - -// void ParseArguments(int argc, char* argv[], configuration& state) { -// // Default Logger Values -// state.logging_type = LoggingType::SSD_WAL; -// state.log_file_dir = TMP_DIR; -// state.data_file_size = 512; - -// state.experiment_type = EXPERIMENT_TYPE_THROUGHPUT; -// state.wait_timeout = 200; -// state.benchmark_type = BENCHMARK_TYPE_YCSB; -// state.flush_mode = 2; -// state.nvm_latency = 0; -// state.pcommit_latency = 0; -// state.asynchronous_mode = ASYNCHRONOUS_TYPE_SYNC; -// state.checkpoint_type = CheckpointTypeId::INVALID; - -// // YCSB Default Values -// ycsb::state.index = IndexType::BWTREE; -// ycsb::state.scale_factor = 1; -// ycsb::state.duration = 10; -// ycsb::state.profile_duration = 1; -// ycsb::state.backend_count = 2; -// ycsb::state.column_count = 10; -// ycsb::state.operation_count = 10; -// ycsb::state.update_ratio = 0.5; -// ycsb::state.zipf_theta = 0.0; -// ycsb::state.exp_backoff = false; -// ycsb::state.string_mode = false; -// ycsb::state.gc_mode = false; -// ycsb::state.gc_backend_count = 1; - -// // TPC-C Default Values -// tpcc::state.index = IndexType::BWTREE; -// tpcc::state.scale_factor = 1; -// tpcc::state.duration = 10; -// tpcc::state.profile_duration = 1; -// tpcc::state.backend_count = 2; -// tpcc::state.warehouse_count = 2; -// tpcc::state.exp_backoff = false; -// tpcc::state.affinity = false; -// tpcc::state.gc_mode = false; -// tpcc::state.gc_backend_count = 1; - - -// // Parse args -// while (1) { -// int idx = 0; -// // logger - hs:x:f:l:t:q:v:r:y: -// // ycsb - hemgi:k:d:p:b:c:o:u:z:n: -// // tpcc - heagi:k:d:p:b:w:n: -// int c = getopt_long(argc, argv, "hs:x:f:l:t:q:v:r:y:emgi:k:d:p:b:c:o:u:z:n:aw:j:", -// opts, &idx); - -// if (c == -1) break; - -// switch (c) { -// case 's': -// state.asynchronous_mode = (AsynchronousType)atoi(optarg); -// break; -// case 'x': -// state.experiment_type = (ExperimentType)atoi(optarg); -// break; -// case 'f': -// state.data_file_size = atoi(optarg); -// break; -// case 'j': -// state.log_file_dir = optarg; -// break; -// case 'l': -// state.logging_type = (LoggingType)atoi(optarg); -// break; -// case 't': -// state.nvm_latency = atoi(optarg); -// break; -// case 'q': -// state.pcommit_latency = atoi(optarg); -// break; -// case 'v': -// state.flush_mode = atoi(optarg); -// break; -// case 'r': -// state.wait_timeout = atoi(optarg); -// break; -// case 'y': -// state.benchmark_type = (BenchmarkType)atoi(optarg); -// break; - -// case 'i': { -// char *index = optarg; -// if (strcmp(index, "btree") == 0) { -// ycsb::state.index = IndexType::BWTREE; -// tpcc::state.index = IndexType::BWTREE; -// } else if (strcmp(index, "bwtree") == 0) { -// ycsb::state.index = IndexType::BWTREE; -// tpcc::state.index = IndexType::BWTREE; -// } else { -// LOG_ERROR("Unknown index: %s", index); -// exit(EXIT_FAILURE); -// } -// break; -// } -// case 'k': -// ycsb::state.scale_factor = atoi(optarg); -// tpcc::state.scale_factor = atof(optarg); -// break; -// case 'd': -// ycsb::state.duration = atof(optarg); -// tpcc::state.duration = atof(optarg); -// break; -// case 'p': -// ycsb::state.profile_duration = atof(optarg); -// tpcc::state.profile_duration = atof(optarg); -// break; -// case 'b': -// ycsb::state.backend_count = atoi(optarg); -// tpcc::state.backend_count = atoi(optarg); -// break; -// case 'c': -// ycsb::state.column_count = atoi(optarg); -// break; -// case 'o': -// ycsb::state.operation_count = atoi(optarg); -// break; -// case 'u': -// ycsb::state.update_ratio = atof(optarg); -// break; -// case 'z': -// ycsb::state.zipf_theta = atof(optarg); -// break; -// case 'e': -// ycsb::state.exp_backoff = true; -// tpcc::state.exp_backoff = true; -// break; -// case 'm': -// ycsb::state.string_mode = true; -// break; -// case 'g': -// ycsb::state.gc_mode = true; -// tpcc::state.gc_mode = true; -// break; -// case 'n': -// ycsb::state.gc_backend_count = atof(optarg); -// tpcc::state.gc_backend_count = atof(optarg); -// break; -// case 'w': -// tpcc::state.warehouse_count = atoi(optarg); -// break; -// case 'a': -// tpcc::state.affinity = true; -// break; - -// case 'h': -// Usage(stderr); -// ycsb::Usage(stderr); -// tpcc::Usage(stderr); -// exit(EXIT_FAILURE); -// break; - -// default: -// fprintf(stderr, "\nUnknown option: -%c-\n", c); -// Usage(stderr); -// ycsb::Usage(stderr); -// tpcc::Usage(stderr); -// exit(EXIT_FAILURE); -// break; -// } -// } - -// if (state.checkpoint_type == CheckpointType::NORMAL && -// (state.logging_type == LoggingType::NVM_WAL || -// state.logging_type == LoggingType::SSD_WAL || -// state.logging_type == LoggingType::HDD_WAL)) { -// peloton_checkpoint_mode = CheckpointType::NORMAL; -// } - -// // Print Logger configuration -// ValidateLoggingType(state); -// ValidateExperimentType(state); -// ValidateAsynchronousMode(state); -// ValidateBenchmarkType(state); -// ValidateDataFileSize(state); -// ValidateLogFileDir(state); -// ValidateWaitTimeout(state); -// ValidateFlushMode(state); -// ValidateNVMLatency(state); -// ValidatePCOMMITLatency(state); - -// // Print YCSB configuration -// if (state.benchmark_type == BENCHMARK_TYPE_YCSB) { -// ycsb::ValidateIndex(ycsb::state); -// ycsb::ValidateScaleFactor(ycsb::state); -// ycsb::ValidateDuration(ycsb::state); -// ycsb::ValidateProfileDuration(ycsb::state); -// ycsb::ValidateBackendCount(ycsb::state); -// ycsb::ValidateColumnCount(ycsb::state); -// ycsb::ValidateOperationCount(ycsb::state); -// ycsb::ValidateUpdateRatio(ycsb::state); -// ycsb::ValidateZipfTheta(ycsb::state); -// ycsb::ValidateGCBackendCount(ycsb::state); -// } -// // Print TPCC configuration -// else if (state.benchmark_type == BENCHMARK_TYPE_TPCC) { -// tpcc::ValidateIndex(tpcc::state); -// tpcc::ValidateScaleFactor(tpcc::state); -// tpcc::ValidateDuration(tpcc::state); -// tpcc::ValidateProfileDuration(tpcc::state); -// tpcc::ValidateBackendCount(tpcc::state); -// tpcc::ValidateWarehouseCount(tpcc::state); -// tpcc::ValidateGCBackendCount(tpcc::state); - -// // Static TPCC parameters -// tpcc::state.item_count = 100000 * tpcc::state.scale_factor; -// tpcc::state.districts_per_warehouse = 10; -// tpcc::state.customers_per_district = 3000 * tpcc::state.scale_factor; -// tpcc::state.new_orders_per_district = 900 * tpcc::state.scale_factor; -// } -// } - -// } // namespace logger -// } // namespace benchmark -// } // namespace peloton diff --git a/src/main/logger/logger_workload.cpp b/src/main/logger/logger_workload.cpp deleted file mode 100644 index dbed1d6dca8..00000000000 --- a/src/main/logger/logger_workload.cpp +++ /dev/null @@ -1,421 +0,0 @@ -// //===----------------------------------------------------------------------===// -// // -// // Peloton -// // -// // logger_workload.cpp -// // -// // Identification: src/main/logger/logger_workload.cpp -// // -// // Copyright (c) 2015-16, Carnegie Mellon University Database Group -// // -// //===----------------------------------------------------------------------===// - -// #include -// #include -// #include -// #include -// #include -// #include - -// #include "type/value_factory.h" -// #include "concurrency/transaction_manager_factory.h" - -// #include "common/exception.h" -// #include "common/logger.h" -// #include "common/timer.h" -// #include "logging/log_manager.h" -// #include "storage/storage_manager.h" - -// #include "benchmark/logger/logger_workload.h" - -// #include "benchmark/ycsb/ycsb_configuration.h" -// #include "benchmark/ycsb/ycsb_loader.h" -// #include "benchmark/ycsb/ycsb_workload.h" - -// #include "benchmark/tpcc/tpcc_configuration.h" -// #include "benchmark/tpcc/tpcc_loader.h" -// #include "benchmark/tpcc/tpcc_workload.h" - -// #include "logging/checkpoint_manager.h" -// #include "logging/loggers/wbl_frontend_logger.h" -// #include "logging/logging_util.h" - -// //===--------------------------------------------------------------------===// -// // GUC Variables -// //===--------------------------------------------------------------------===// - -// extern peloton::CheckpointType peloton_checkpoint_mode; - -// namespace peloton { -// namespace benchmark { -// namespace logger { - -// //===--------------------------------------------------------------------===// -// // PREPARE LOG FILE -// //===--------------------------------------------------------------------===// - -// //===--------------------------------------------------------------------===// -// // 1. Standby -- Bootstrap -// // 2. Recovery -- Optional -// // 3. Logging -- Collect data and flush when commit -// // 4. Terminate -- Collect any remaining data and flush -// // 5. Sleep -- Disconnect backend loggers and frontend logger from manager -// //===--------------------------------------------------------------------===// - -// #define LOGGING_TESTS_DATABASE_OID 20000 -// #define LOGGING_TESTS_TABLE_OID 10000 - -// void WriteOutput() { -// std::ofstream out("outputfile-log.summary"); -// LOG_INFO("----------------------------------------------------------"); -// LOG_INFO("%d %d %d %d %d %d", state.benchmark_type, static_cast(state.logging_type), -// state.nvm_latency, state.pcommit_latency, state.flush_mode, -// state.asynchronous_mode); - -// out << state.benchmark_type << " "; -// out << state.logging_type << " "; -// out << state.nvm_latency << " "; -// out << state.pcommit_latency << " "; -// out << state.flush_mode << " "; -// out << state.asynchronous_mode << "\n"; -// out.flush(); -// } - -// std::string GetFilePath(std::string directory_path, std::string file_name) { -// std::string file_path = directory_path; - -// // Add a trailing slash to a file path if needed -// if (!file_path.empty() && file_path.back() != '/') file_path += '/'; - -// file_path += file_name; - -// return file_path; -// } - -// void StartLogging(std::thread& log_thread, std::thread& checkpoint_thread) { -// auto& log_manager = logging::LogManager::GetInstance(); - -// if (peloton_checkpoint_mode != CheckpointTypeId::INVALID) { -// auto& checkpoint_manager = -// peloton::logging::CheckpointManager::GetInstance(); - -// // launch checkpoint thread -// if (!checkpoint_manager.IsInCheckpointingMode()) { -// // Wait for standby mode -// auto local_thread = -// std::thread(&peloton::logging::CheckpointManager::StartStandbyMode, -// &checkpoint_manager); -// checkpoint_thread.swap(local_thread); -// checkpoint_manager.WaitForModeTransition( -// peloton::CheckpointStatus::STANDBY, true); - -// // Clean up table tile state before recovery from checkpoint -// log_manager.PrepareRecovery(); - -// // Do any recovery -// checkpoint_manager.StartRecoveryMode(); - -// // Wait for standby mode -// checkpoint_manager.WaitForModeTransition( -// peloton::CheckpointStatus::DONE_RECOVERY, true); -// } - -// // start checkpointing mode after recovery -// if (peloton_checkpoint_mode != CheckpointTypeId::INVALID) { -// if (!checkpoint_manager.IsInCheckpointingMode()) { -// // Now, enter CHECKPOINTING mode -// checkpoint_manager.SetCheckpointStatus( -// peloton::CheckpointStatus::CHECKPOINTING); -// } -// } -// } - -// if (peloton_logging_mode != LoggingTypeId::INVALID) { -// // Launching a thread for logging -// if (!log_manager.IsInLoggingMode()) { -// // Wait for standby mode -// auto local_thread = std::thread( -// &peloton::logging::LogManager::StartStandbyMode, &log_manager); -// log_thread.swap(local_thread); -// log_manager.WaitForModeTransition(peloton::LoggingStatusType::STANDBY, -// true); - -// // Clean up database tile state before recovery from checkpoint -// log_manager.PrepareRecovery(); - -// // Do any recovery -// log_manager.StartRecoveryMode(); - -// // Wait for logging mode -// log_manager.WaitForModeTransition(peloton::LoggingStatusType::LOGGING, -// true); - -// // Done recovery -// log_manager.DoneRecovery(); -// } -// } -// } - -// int RemoveDirectory(const char* dir) { -// int ret = 0; -// FTS* ftsp = NULL; -// FTSENT* curr; - -// // Cast needed (in C) because fts_open() takes a "char * const *", instead -// // of a "const char * const *", which is only allowed in C++. fts_open() -// // does not modify the argument. -// char* files[] = {(char*)dir, NULL}; - -// // FTS_NOCHDIR - Avoid changing cwd, which could cause unexpected behavior -// // in multithreaded programs -// // FTS_PHYSICAL - Don't follow symlinks. Prevents deletion of files outside -// // of the specified directory -// // FTS_XDEV - Don't cross filesystem boundaries -// ftsp = fts_open(files, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL); -// if (!ftsp) { -// fprintf(stderr, "%s: fts_open failed: %s\n", dir, strerror(errno)); -// ret = -1; -// goto finish; -// } - -// while ((curr = fts_read(ftsp))) { -// switch (curr->fts_info) { -// case FTS_NS: -// case FTS_DNR: -// case FTS_ERR: -// break; - -// case FTS_DC: -// case FTS_DOT: -// case FTS_NSOK: -// // Not reached unless FTS_LOGICAL, FTS_SEEDOT, or FTS_NOSTAT were -// // passed to fts_open() -// break; - -// case FTS_D: -// // Do nothing. Need depth-first search, so directories are deleted -// // in FTS_DP -// break; - -// case FTS_DP: -// case FTS_F: -// case FTS_SL: -// case FTS_SLNONE: -// case FTS_DEFAULT: -// if (remove(curr->fts_accpath) < 0) { -// fprintf(stderr, "%s: Failed to remove: %s\n", curr->fts_path, -// strerror(errno)); -// ret = -1; -// } -// break; -// } -// } - -// finish: -// if (ftsp) { -// fts_close(ftsp); -// } - -// return ret; -// } - -// void CleanUpLogDirectory() { -// if (chdir(state.log_file_dir.c_str())) { -// LOG_ERROR("Could not change directory"); -// } -// // remove wbl log file if it exists -// std::string wbl_directory_path = -// state.log_file_dir + logging::WriteBehindFrontendLogger::wbl_log_path; - -// // remove wal log directory (for wal if it exists) -// // for now hardcode for 1 logger -// std::string wal_directory_path = -// state.log_file_dir + -// logging::WriteAheadFrontendLogger::wal_directory_path; - -// std::string checkpoint_dir_path = state.log_file_dir + "pl_checkpoint"; - -// RemoveDirectory(wbl_directory_path.c_str()); - -// RemoveDirectory(wal_directory_path.c_str()); -// } - -// /** -// * @brief writing a simple log file -// */ -// bool PrepareLogFile() { -// // Clean up log directory -// CleanUpLogDirectory(); - -// // start a thread for logging -// auto& log_manager = logging::LogManager::GetInstance(); -// log_manager.SetLogDirectoryName(state.log_file_dir); - -// if (logging::LoggingUtil::IsBasedOnWriteAheadLogging(peloton_logging_mode)) { -// log_manager.SetLogFileName( -// state.log_file_dir + "/" + -// logging::WriteAheadFrontendLogger::wal_directory_path); -// } else { -// LOG_ERROR("currently, we do not support write behind logging."); -// PELOTON_ASSERT(false); -// } - -// UNUSED_ATTRIBUTE auto& checkpoint_manager = -// logging::CheckpointManager::GetInstance(); - -// if (log_manager.ContainsFrontendLogger() == true) { -// LOG_ERROR("another logging thread is running now"); -// return false; -// } - -// // Get an instance of the storage manager to force posix_fallocate -// // to be invoked before we begin benchmarking -// auto& storage_manager = storage::StorageManager::GetInstance(); -// auto tmp = storage_manager.Allocate(BackendType::MM, 1024); -// storage_manager.Release(BackendType::MM, tmp); - -// // Pick sync commit mode -// switch (state.asynchronous_mode) { -// case ASYNCHRONOUS_TYPE_SYNC: -// log_manager.SetSyncCommit(true); -// break; - -// case ASYNCHRONOUS_TYPE_ASYNC: -// log_manager.SetSyncCommit(false); -// break; - -// case ASYNCHRONOUS_TYPE_DISABLED: -// // No logging -// peloton_logging_mode = LoggingTypeId::INVALID; -// break; -// case ASYNCHRONOUS_TYPE_NO_WRITE: -// log_manager.SetNoWrite(true); -// break; - -// case ASYNCHRONOUS_TYPE_INVALID: -// throw Exception("Invalid asynchronous mode : " + -// std::to_string(state.asynchronous_mode)); -// } - -// std::thread logging_thread; -// std::thread checkpoint_thread; - -// // Initializing logging module -// StartLogging(logging_thread, checkpoint_thread); - -// // Build the log -// BuildLog(); - -// // Stop frontend logger if in a valid logging mode -// if (peloton_checkpoint_mode != CheckpointTypeId::INVALID) { -// // Wait for the mode transition :: LOGGING -> TERMINATE -> SLEEP -// checkpoint_manager.SetCheckpointStatus(CheckpointStatus::INVALID); -// checkpoint_manager.WaitForModeTransition(CheckpointStatus::INVALID, true); -// checkpoint_thread.join(); -// } -// // Stop frontend logger if in a valid logging mode -// if (peloton_logging_mode != LoggingTypeId::INVALID) { -// // Wait for the mode transition :: LOGGING -> TERMINATE -> SLEEP -// if (log_manager.EndLogging()) { -// logging_thread.join(); -// } -// } - -// if (state.benchmark_type == BENCHMARK_TYPE_YCSB) { -// ycsb::WriteOutput(); -// } else if (state.benchmark_type == BENCHMARK_TYPE_TPCC) { -// tpcc::WriteOutput(); -// } - -// return true; -// } - -// //===--------------------------------------------------------------------===// -// // CHECK RECOVERY -// //===--------------------------------------------------------------------===// - -// void ResetSystem() { -// auto& txn_manager = concurrency::TransactionManagerFactory::GetInstance(); -// txn_manager.ResetStates(); - -// // Reset database (only needed for WAL not WBL) -// if (state.benchmark_type == BENCHMARK_TYPE_YCSB) { -// ycsb::CreateYCSBDatabase(); -// } else if (state.benchmark_type == BENCHMARK_TYPE_TPCC) { -// tpcc::CreateTPCCDatabase(); -// } -// } - -// /** -// * @brief recover the database and check the tuples -// */ -// void DoRecovery() { -// //===--------------------------------------------------------------------===// -// // RECOVERY -// //===--------------------------------------------------------------------===// - -// // Reset log manager state -// auto& log_manager = peloton::logging::LogManager::GetInstance(); -// log_manager.ResetLogStatus(); -// log_manager.ResetFrontendLoggers(); - -// Timer timer; -// std::thread thread; -// std::thread cp_thread; - -// timer.Start(); - -// // Do recovery -// StartLogging(thread, cp_thread); - -// timer.Stop(); - -// // Synchronize and finish recovery -// if (peloton_logging_mode != LoggingTypeId::INVALID) { -// if (log_manager.EndLogging()) { -// thread.join(); -// } else { -// LOG_ERROR("Failed to terminate logging thread"); -// } -// } -// auto& checkpoint_manager = logging::CheckpointManager::GetInstance(); -// // Synchronize and finish recovery -// if (peloton_checkpoint_mode != CheckpointTypeId::INVALID) { -// checkpoint_manager.SetCheckpointStatus(CheckpointStatus::INVALID); -// checkpoint_manager.WaitForModeTransition(CheckpointStatus::INVALID, true); -// cp_thread.join(); -// } - -// if (state.benchmark_type == BENCHMARK_TYPE_YCSB) { -// ycsb::WriteOutput(); -// } else if (state.benchmark_type == BENCHMARK_TYPE_TPCC) { -// tpcc::WriteOutput(); -// } - -// // Recovery time (in ms) -// LOG_INFO("recovery time: %lf", timer.GetDuration()); -// } - -// //===--------------------------------------------------------------------===// -// // WRITING LOG RECORD -// //===--------------------------------------------------------------------===// - -// void BuildLog() { -// if (state.benchmark_type == BENCHMARK_TYPE_YCSB) { -// ycsb::CreateYCSBDatabase(); - -// ycsb::LoadYCSBDatabase(); - -// ycsb::RunWorkload(); -// } else if (state.benchmark_type == BENCHMARK_TYPE_TPCC) { -// tpcc::CreateTPCCDatabase(); - -// tpcc::LoadTPCCDatabase(); - -// tpcc::RunWorkload(); -// } -// } - -// } // namespace logger -// } // namespace benchmark -// } // namespace peloton diff --git a/src/main/sdbench/sdbench.cpp b/src/main/sdbench/sdbench.cpp deleted file mode 100644 index aaaa834f3d5..00000000000 --- a/src/main/sdbench/sdbench.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench.cpp -// -// Identification: src/main/sdbench/sdbench.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include - -#include "common/logger.h" -#include "benchmark/sdbench/sdbench_configuration.h" -#include "benchmark/sdbench/sdbench_workload.h" -#include "benchmark/sdbench/sdbench_loader.h" -#include "concurrency/epoch_manager_factory.h" - -#include - -namespace peloton { -namespace benchmark { -namespace sdbench { - -configuration state; - -// Main Entry Point -void RunBenchmark() { - - concurrency::EpochManagerFactory::Configure(EpochType::DECENTRALIZED_EPOCH); - - std::unique_ptr epoch_thread; - - concurrency::EpochManager &epoch_manager = concurrency::EpochManagerFactory::GetInstance(); - - epoch_manager.RegisterThread(0); - - epoch_manager.StartEpoch(epoch_thread); - - if (state.multi_stage) { - // Run holistic indexing comparison benchmark - RunMultiStageBenchmark(); - } else { - // Run a single sdbench test - RunSDBenchTest(); - } - - epoch_manager.StopEpoch(); - - epoch_thread->join(); -} - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton - -int main(int argc, char **argv) { - peloton::benchmark::sdbench::ParseArguments( - argc, argv, peloton::benchmark::sdbench::state); - - peloton::benchmark::sdbench::RunBenchmark(); - - peloton::benchmark::sdbench::sdbench_table.release(); - - // shutdown protocol buf library - google::protobuf::ShutdownProtobufLibrary(); - - return 0; -} diff --git a/src/main/sdbench/sdbench_configuration.cpp b/src/main/sdbench/sdbench_configuration.cpp deleted file mode 100644 index 09047892eef..00000000000 --- a/src/main/sdbench/sdbench_configuration.cpp +++ /dev/null @@ -1,566 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench_configuration.cpp -// -// Identification: src/main/sdbench/sdbench_configuration.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include - -#include "benchmark/sdbench/sdbench_configuration.h" -#include "common/logger.h" - -namespace peloton { -namespace benchmark { -namespace sdbench { - -void Usage() { - LOG_INFO( - "\n" - "Command line options : sdbench \n" - " -a --attribute_count : # of attributes\n" - " -b --convergence_query_threshold : # of queries for convergence\n" - " -c --query_complexity_type : Complexity of query\n" - " -d --variability_threshold : Variability threshold\n" - " -e --index_usage_type : Index usage type\n" - " -f --analyze_sample_count_threshold : Analyze speed \n" - " -g --tuples_per_tg : # of tuples per tilegroup\n" - " -h --help : Print help message\n" - " -i --duration_between_pauses : Duration between pauses\n" - " -j --duration_of_pause : Duration of pause\n" - " -k --scale-factor : # of tile groups\n" - " -l --layout : Layout\n" - " -m --max_tile_groups_indexed : Max tile groups indexed\n" - " -n --multi_stage : Run multi stage experiment\n" - " -o --convergence : Convergence\n" - " -p --projectivity : Projectivity\n" - " -q --total_ops : # of operations\n" - " -r --holistic_indexing : Run with holistic indexing\n" - " -s --selectivity : Selectivity\n" - " -t --phase_length : Length of a phase\n" - " -u --write_complexity_type : Complexity of write\n" - " -v --verbose : Output verbosity\n" - " -w --write_ratio : Fraction of writes\n" - " -x --index_count_threshold : Index count threshold\n" - " -y --index_utility_threshold : Index utility threshold\n" - " -z --write_ratio_threshold : Write ratio threshold\n"); - - exit(EXIT_FAILURE); -} - -static struct option opts[] = { - {"attribute_count", optional_argument, NULL, 'a'}, - {"convergence_query_threshold", optional_argument, NULL, 'b'}, - {"query_complexity_type", optional_argument, NULL, 'c'}, - {"variability_threshold", optional_argument, NULL, 'd'}, - {"tuner_mode_type", optional_argument, NULL, 'e'}, - {"tuples_per_tg", optional_argument, NULL, 'g'}, - {"duration_between_pauses", optional_argument, NULL, 'i'}, - {"duration_of_pause", optional_argument, NULL, 'j'}, - {"scale-factor", optional_argument, NULL, 'k'}, - {"layout", optional_argument, NULL, 'l'}, - {"max_tile_groups_indexed", optional_argument, NULL, 'm'}, - {"convergence", optional_argument, NULL, 'o'}, - {"projectivity", optional_argument, NULL, 'p'}, - {"total_ops", optional_argument, NULL, 'q'}, - {"selectivity", optional_argument, NULL, 's'}, - {"phase_length", optional_argument, NULL, 't'}, - {"write_complexity_type", optional_argument, NULL, 'u'}, - {"verbose", optional_argument, NULL, 'v'}, - {"write_ratio", optional_argument, NULL, 'w'}, - {"index_count_threshold", optional_argument, NULL, 'x'}, - {"index_utility_threshold", optional_argument, NULL, 'y'}, - {"write_ratio_threshold", optional_argument, NULL, 'z'}, - {"multi_stage", optional_argument, NULL, 'n'}, - {"holistic_indexing", optional_argument, NULL, 'r'}, - {NULL, 0, NULL, 0}}; - -void GenerateSequence(oid_t column_count) { - // Reset sequence - sdbench_column_ids.clear(); - - // Generate sequence - for (oid_t column_id = 1; column_id <= column_count; column_id++) - sdbench_column_ids.push_back(column_id); - - std::random_shuffle(sdbench_column_ids.begin(), sdbench_column_ids.end()); -} - -static void ValidateIndexUsageType(const configuration &state) { - if (state.index_usage_type < 1 || state.index_usage_type > 5) { - LOG_ERROR("Invalid index_usage_type :: %d", state.index_usage_type); - exit(EXIT_FAILURE); - } else { - switch (state.index_usage_type) { - case INDEX_USAGE_TYPE_PARTIAL_FAST: - LOG_INFO("%s : PARTIAL_FAST", "index_usage_type "); - break; - case INDEX_USAGE_TYPE_PARTIAL_MEDIUM: - LOG_INFO("%s : PARTIAL_MEDIUM", "index_usage_type "); - break; - case INDEX_USAGE_TYPE_PARTIAL_SLOW: - LOG_INFO("%s : PARTIAL_SLOW", "index_usage_type "); - break; - case INDEX_USAGE_TYPE_NEVER: - LOG_INFO("%s : NEVER", "index_usage_type "); - break; - case INDEX_USAGE_TYPE_FULL: - LOG_INFO("%s : FULL", "index_usage_type "); - break; - default: - break; - } - } -} - -static void ValidateQueryComplexityType(const configuration &state) { - if (state.query_complexity_type < 1 || state.query_complexity_type > 3) { - LOG_ERROR("Invalid query_complexity_type :: %d", - state.query_complexity_type); - exit(EXIT_FAILURE); - } else { - switch (state.query_complexity_type) { - case QUERY_COMPLEXITY_TYPE_SIMPLE: - LOG_INFO("%s : SIMPLE", "query_complexity_type "); - break; - case QUERY_COMPLEXITY_TYPE_MODERATE: - LOG_INFO("%s : MODERATE", "query_complexity_type "); - break; - case QUERY_COMPLEXITY_TYPE_COMPLEX: - LOG_INFO("%s : COMPLEX", "query_complexity_type "); - break; - default: - break; - } - } -} - -static void ValidateWriteComplexityType(const configuration &state) { - if (state.write_complexity_type < 1 || state.write_complexity_type > 3) { - LOG_ERROR("Invalid write_complexity_type :: %d", - state.write_complexity_type); - exit(EXIT_FAILURE); - } else { - switch (state.write_complexity_type) { - case WRITE_COMPLEXITY_TYPE_SIMPLE: - LOG_INFO("write_complexity_type : SIMPLE"); - break; - case WRITE_COMPLEXITY_TYPE_COMPLEX: - LOG_INFO("write_complexity_type : COMPLEX"); - break; - case WRITE_COMPLEXITY_TYPE_INSERT: - LOG_INFO("write_complexity_type: INSERT"); - break; - default: - break; - } - } -} - -static void ValidateScaleFactor(const configuration &state) { - if (state.scale_factor <= 0) { - LOG_ERROR("Invalid scale_factor :: %d", state.scale_factor); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %d", "scale_factor", state.scale_factor); -} - -static void ValidateLayout(const configuration &state) { - if (state.layout_mode == LayoutType::INVALID) { - LOG_ERROR("Invalid layout :: %s", - LayoutTypeToString(state.layout_mode).c_str()); - exit(EXIT_FAILURE); - } else { - switch (state.layout_mode) { - case LayoutType::ROW: - LOG_INFO("%s : ROW", "layout "); - break; - case LayoutType::COLUMN: - LOG_INFO("%s : COLUMN", "layout "); - break; - case LayoutType::HYBRID: - LOG_INFO("%s : HYBRID", "layout "); - break; - default: - break; - } - } -} - -static void ValidateProjectivity(const configuration &state) { - if (state.projectivity < 0 || state.projectivity > 1) { - LOG_ERROR("Invalid projectivity :: %.1lf", state.projectivity); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %.3lf", "projectivity", state.projectivity); -} - -static void ValidateSelectivity(const configuration &state) { - if (state.selectivity < 0 || state.selectivity > 1) { - LOG_ERROR("Invalid selectivity :: %.1lf", state.selectivity); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %.3lf", "selectivity", state.selectivity); -} - -static void ValidateAttributeCount(const configuration &state) { - if (state.attribute_count <= 0) { - LOG_ERROR("Invalid column_count :: %d", state.attribute_count); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %d", "column_count", state.attribute_count); -} - -static void ValidateWriteRatio(const configuration &state) { - if (state.write_ratio < 0 || state.write_ratio > 1) { - LOG_ERROR("Invalid write_ratio :: %.1lf", state.write_ratio); - exit(EXIT_FAILURE); - } - - if (state.write_ratio == 0) { - LOG_INFO("%s : READ_ONLY", "write_ratio"); - } else if (state.write_ratio == 0.1) { - LOG_INFO("%s : READ_HEAVY", "write_ratio"); - } else if (state.write_ratio == 0.5) { - LOG_INFO("%s : BALANCED", "write_ratio"); - } else if (state.write_ratio == 0.9) { - LOG_INFO("%s : WRITE_HEAVY", "write_ratio"); - } else { - LOG_INFO("%s : %.1lf", "write_ratio", state.write_ratio); - } -} - -static void ValidateTotalOps(const configuration &state) { - if (state.total_ops <= 0) { - LOG_ERROR("Invalid total_ops :: %lu", state.total_ops); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %ld", "total_ops", state.total_ops); -} - -static void ValidatePhaseLength(const configuration &state) { - if (state.phase_length <= 0) { - LOG_ERROR("Invalid phase_length :: %lu", state.phase_length); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %lu", "phase_length", state.phase_length); -} - -static void ValidateTuplesPerTileGroup(const configuration &state) { - if (state.tuples_per_tilegroup <= 0) { - LOG_ERROR("Invalid tuples_per_tilegroup :: %d", state.tuples_per_tilegroup); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %d", "tuples_per_tilegroup", state.tuples_per_tilegroup); -} - -static void ValidateDurationBetweenPauses(const configuration &state) { - if (state.duration_between_pauses <= 0) { - LOG_ERROR("Invalid duration_between_pauses :: %u", - state.duration_between_pauses); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "duration_between_pauses", state.duration_between_pauses); -} - -static void ValidateDurationOfPause(const configuration &state) { - if (state.duration_of_pause <= 0) { - LOG_ERROR("Invalid duration_of_pause :: %u", state.duration_of_pause); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "duration_of_pause", state.duration_of_pause); -} - -static void ValidateAnalyzeSampleCountThreshold(const configuration &state) { - if (state.analyze_sample_count_threshold <= 0) { - LOG_ERROR("Invalid analyze_sample_count_threshold :: %u", - state.analyze_sample_count_threshold); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "analyze_sample_count_threshold", - state.analyze_sample_count_threshold); -} - -static void ValidateMaxTileGroupsIndexed(const configuration &state) { - if (state.tile_groups_indexed_per_iteration <= 0) { - LOG_ERROR("Invalid max_tile_groups_indexed :: %u", - state.tile_groups_indexed_per_iteration); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "max_tile_groups_indexed", - state.tile_groups_indexed_per_iteration); -} - -static void ValidateConvergence(const configuration &state) { - if (state.convergence == true) { - LOG_INFO("%s : %s", "convergence", "true"); - } -} - -static void ValidateQueryConvergenceThreshold(const configuration &state) { - if (state.convergence_op_threshold <= 0) { - LOG_ERROR("Invalid convergence_query_threshold :: %u", - state.convergence_op_threshold); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "convergence_query_threshold", - state.convergence_op_threshold); -} - -static void ValidateVariabilityThreshold(const configuration &state) { - if (state.variability_threshold <= 0 || state.variability_threshold > 1000) { - LOG_ERROR("Invalid variability_threshold :: %u", - state.variability_threshold); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "variability_threshold", state.variability_threshold); -} - -static void ValidateIndexCountThreshold(const configuration &state) { - if (state.index_count_threshold == 0) { - LOG_ERROR("Invalid index_count_threshold :: %u", - state.index_count_threshold); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %u", "index_count_threshold", state.index_count_threshold); -} - -static void ValidateIndexUtilityThreshold(const configuration &state) { - if (state.index_utility_threshold < 0 || state.index_utility_threshold > 1) { - LOG_ERROR("Invalid index_utility_threshold :: %.2lf", - state.index_utility_threshold); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %.2lf", "index_utility_threshold", - state.index_utility_threshold); -} - -static void ValidateWriteRatioThreshold(const configuration &state) { - if (state.write_ratio_threshold < 0 || state.write_ratio_threshold > 1) { - LOG_ERROR("Invalid write_ratio_threshold :: %.2lf", - state.write_ratio_threshold); - exit(EXIT_FAILURE); - } - - LOG_INFO("%s : %.2lf", "write_ratio_threshold", state.write_ratio_threshold); -} - -static void ValidateMultiStage(const configuration &state) { - LOG_INFO("multi_stage: %d", state.multi_stage); -} - -static void ValidateHolisticIndexing(const configuration &state) { - LOG_INFO("holistic_indexing : %d", state.holistic_indexing); -} - -void ParseArguments(int argc, char *argv[], configuration &state) { - state.verbose = false; - - // Default Values - state.index_usage_type = INDEX_USAGE_TYPE_PARTIAL_FAST; - state.query_complexity_type = QUERY_COMPLEXITY_TYPE_SIMPLE; - state.write_complexity_type = WRITE_COMPLEXITY_TYPE_SIMPLE; - - // Scale and attribute count - state.scale_factor = 100.0; - state.attribute_count = 200; - - state.write_ratio = 0.0; - state.tuples_per_tilegroup = DEFAULT_TUPLES_PER_TILEGROUP; - - // Phase parameters - state.total_ops = 10; - state.phase_length = 10; - - // Query parameters - state.selectivity = 0.001; - state.projectivity = 0.01; - - // Layout parameter - state.layout_mode = LayoutType::ROW; - - // Learning rate - state.analyze_sample_count_threshold = 100; - state.duration_between_pauses = 10; - state.duration_of_pause = 100; - state.tile_groups_indexed_per_iteration = 10; - - // Convergence parameters - state.convergence = false; - state.convergence_op_threshold = 200; - - // Variability parameters - state.variability_threshold = 100; - - // Drop parameters - state.index_utility_threshold = 0.25; - state.index_count_threshold = 10; - state.write_ratio_threshold = 0.75; - state.multi_stage = false; - state.holistic_indexing = false; - state.multi_stage_idx = 0; - - // Parse args - while (1) { - int idx = 0; - int c = getopt_long(argc, argv, - "a:b:c:d:e:f:g:hi:j:k:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z:", - opts, &idx); - - if (c == -1) break; - - switch (c) { - // AVAILABLE FLAGS: rABCDEFGHIJKLMNOPQRSTUVWXYZ - case 'a': - state.attribute_count = atoi(optarg); - break; - case 'b': - state.convergence_op_threshold = atoi(optarg); - break; - case 'c': - state.query_complexity_type = (QueryComplexityType)atoi(optarg); - break; - case 'd': - state.variability_threshold = atoi(optarg); - break; - case 'e': - state.index_usage_type = (IndexUsageType)atoi(optarg); - break; - case 'f': - state.analyze_sample_count_threshold = atoi(optarg); - break; - case 'g': - state.tuples_per_tilegroup = atoi(optarg); - break; - case 'h': - Usage(); - break; - case 'i': - state.duration_between_pauses = atoi(optarg); - break; - case 'j': - state.duration_of_pause = atoi(optarg); - break; - case 'k': - state.scale_factor = atoi(optarg); - break; - case 'l': - state.layout_mode = (LayoutType)atoi(optarg); - break; - case 'm': - state.tile_groups_indexed_per_iteration = atoi(optarg); - break; - case 'n': - state.multi_stage = atoi(optarg); - break; - case 'o': - state.convergence = atoi(optarg); - break; - case 'p': - state.projectivity = atof(optarg); - break; - case 'q': - state.total_ops = atol(optarg); - break; - case 'r': - state.holistic_indexing = atoi(optarg); - break; - case 's': - state.selectivity = atof(optarg); - break; - case 't': - state.phase_length = atol(optarg); - break; - case 'u': - state.write_complexity_type = (WriteComplexityType)atoi(optarg); - break; - case 'v': - state.verbose = atoi(optarg); - break; - case 'w': - state.write_ratio = atof(optarg); - break; - case 'x': - state.index_count_threshold = atoi(optarg); - break; - case 'y': - state.index_utility_threshold = atof(optarg); - break; - case 'z': - state.write_ratio_threshold = atof(optarg); - break; - - default: - LOG_ERROR("Unknown option: -%c-", c); - Usage(); - } - } - - ValidateIndexUsageType(state); - - /// Set duration between pauses based on index usage type - if (state.index_usage_type == INDEX_USAGE_TYPE_PARTIAL_FAST) { - state.duration_between_pauses = 10000; - } else if (state.index_usage_type == INDEX_USAGE_TYPE_PARTIAL_MEDIUM) { - state.duration_between_pauses = 1000; - } else if (state.index_usage_type == INDEX_USAGE_TYPE_PARTIAL_SLOW) { - state.duration_between_pauses = 100; - } else if (state.index_usage_type == INDEX_USAGE_TYPE_FULL) { - state.duration_between_pauses = 10000; - } - - /// Check variability threshold - if(state.variability_threshold >= state.attribute_count){ - LOG_ERROR("Variability threshold higher than attribute count"); - exit(EXIT_FAILURE); - } - - ValidateWriteRatio(state); - ValidateQueryComplexityType(state); - ValidateWriteComplexityType(state); - ValidateScaleFactor(state); - ValidateAttributeCount(state); - ValidateTuplesPerTileGroup(state); - ValidateTotalOps(state); - ValidatePhaseLength(state); - ValidateSelectivity(state); - ValidateProjectivity(state); - ValidateLayout(state); - ValidateIndexCountThreshold(state); - ValidateIndexUtilityThreshold(state); - ValidateWriteRatioThreshold(state); - ValidateDurationOfPause(state); - ValidateDurationBetweenPauses(state); - ValidateAnalyzeSampleCountThreshold(state); - ValidateMaxTileGroupsIndexed(state); - ValidateConvergence(state); - ValidateQueryConvergenceThreshold(state); - ValidateVariabilityThreshold(state); - ValidateMultiStage(state); - ValidateHolisticIndexing(state); -} - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton diff --git a/src/main/sdbench/sdbench_loader.cpp b/src/main/sdbench/sdbench_loader.cpp deleted file mode 100644 index 41ce49e4efa..00000000000 --- a/src/main/sdbench/sdbench_loader.cpp +++ /dev/null @@ -1,136 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench_loader.cpp -// -// Identification: src/main/sdbench/sdbench_loader.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/sdbench/sdbench_loader.h" -#include "benchmark/sdbench/sdbench_configuration.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "catalog/manager.h" -#include "catalog/schema.h" -#include "common/item_pointer.h" -#include "common/logger.h" -#include "common/macros.h" -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" -#include "executor/abstract_executor.h" -#include "executor/insert_executor.h" -#include "executor/executor_context.h" -#include "expression/constant_value_expression.h" -#include "index/index_factory.h" -#include "planner/insert_plan.h" -#include "storage/data_table.h" -#include "storage/table_factory.h" -#include "storage/tile.h" -#include "storage/tile_group.h" -#include "type/ephemeral_pool.h" -#include "type/value_factory.h" - -namespace peloton { -namespace benchmark { -namespace sdbench { - -std::unique_ptr sdbench_table; - -void CreateTable(UNUSED_ATTRIBUTE peloton::LayoutType layout_type) { - const oid_t col_count = state.attribute_count + 1; - const bool is_inlined = true; - - // Create schema first - std::vector columns; - - for (oid_t col_itr = 0; col_itr < col_count; col_itr++) { - auto column = catalog::Column(type::TypeId::INTEGER, - type::Type::GetTypeSize(type::TypeId::INTEGER), - "" + std::to_string(col_itr), is_inlined); - - columns.push_back(column); - } - - catalog::Schema *table_schema = new catalog::Schema(columns); - std::string table_name("SDBENCHTABLE"); - - ///////////////////////////////////////////////////////// - // Create table. - ///////////////////////////////////////////////////////// - - bool own_schema = true; - bool adapt_table = true; - sdbench_table.reset(storage::TableFactory::GetDataTable( - INVALID_OID, INVALID_OID, table_schema, table_name, - state.tuples_per_tilegroup, own_schema, adapt_table)); -} - -void LoadTable() { - const oid_t col_count = state.attribute_count + 1; - const int tuple_count = state.scale_factor * state.tuples_per_tilegroup; - - auto table_schema = sdbench_table->GetSchema(); - - ///////////////////////////////////////////////////////// - // Load in the data - ///////////////////////////////////////////////////////// - - // Insert tuples into tile_group. - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - const bool allocate = true; - auto txn = txn_manager.BeginTransaction(); - std::unique_ptr pool(new type::EphemeralPool()); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - for (int rowid = 0; rowid < tuple_count; rowid++) { - int populate_value = rowid; - - std::unique_ptr tuple(new storage::Tuple(table_schema, allocate)); - - for (oid_t col_itr = 0; col_itr < col_count; col_itr++) { - auto value = type::ValueFactory::GetIntegerValue(populate_value); - tuple->SetValue(col_itr, value, pool.get()); - } - - planner::InsertPlan node(sdbench_table.get(), std::move(tuple)); - executor::InsertExecutor executor(&node, context.get()); - executor.Execute(); - } - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - LOG_TRACE("commit successfully"); - } else { - LOG_TRACE("commit failed"); - } -} - -void CreateAndLoadTable(LayoutType layout_type) { - - CreateTable(layout_type); - - LoadTable(); -} - -void DropIndexes() { - // Drop index - sdbench_table->DropIndexWithOid(0); -} - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton diff --git a/src/main/sdbench/sdbench_workload.cpp b/src/main/sdbench/sdbench_workload.cpp deleted file mode 100644 index 3d50b037e8c..00000000000 --- a/src/main/sdbench/sdbench_workload.cpp +++ /dev/null @@ -1,1545 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// sdbench_workload.cpp -// -// Identification: src/main/sdbench/sdbench_workload.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tuning/index_tuner.h" -#include "tuning/layout_tuner.h" -#include "tuning/sample.h" - -#include "benchmark/sdbench/sdbench_loader.h" -#include "benchmark/sdbench/sdbench_workload.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/macros.h" -#include "common/timer.h" -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/aggregate_executor.h" -#include "executor/executor_context.h" -#include "executor/hybrid_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/nested_loop_join_executor.h" -#include "executor/projection_executor.h" -#include "executor/seq_scan_executor.h" -#include "executor/update_executor.h" - -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/conjunction_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/operator_expression.h" -#include "expression/tuple_value_expression.h" - -#include "planner/abstract_plan.h" -#include "planner/aggregate_plan.h" -#include "planner/hybrid_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/materialization_plan.h" -#include "planner/nested_loop_join_plan.h" -#include "planner/projection_plan.h" -#include "planner/seq_scan_plan.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" -#include "storage/tile.h" -#include "storage/tile_group.h" -#include "storage/tile_group_header.h" - -namespace peloton { -namespace benchmark { -namespace sdbench { - -// Function definitions -static std::shared_ptr PickIndex(storage::DataTable *table, - std::vector query_attrs); - -static void AggregateQueryHelper(const std::vector &tuple_key_attrs, - const std::vector &index_key_attrs); - -static void JoinQueryHelper( - const std::vector &left_table_tuple_key_attrs, - const std::vector &left_table_index_key_attrs, - const std::vector &right_table_tuple_key_attrs, - const std::vector &right_table_index_key_attrs, - const oid_t left_table_join_column, const oid_t right_table_join_column); - -// Tuple id counter -oid_t sdbench_tuple_counter = -1000000; - -std::vector column_counts = {50, 500}; - -// Index tuner -tuning::IndexTuner &index_tuner = tuning::IndexTuner::GetInstance(); - -// Layout tuner -tuning::LayoutTuner &layout_tuner = tuning::LayoutTuner::GetInstance(); - -// Predicate generator -std::vector> predicate_distribution; - -// Bitmap for already used predicate -#define MAX_PREDICATE_ATTR 10 -bool predicate_used[MAX_PREDICATE_ATTR][MAX_PREDICATE_ATTR] - [MAX_PREDICATE_ATTR] = {}; - -std::size_t predicate_distribution_size = 0; - -static void CopyColumn(oid_t col_itr); - -static void GeneratePredicateDistribution() { - for (oid_t i = 1; i <= 9; i++) { - for (oid_t j = 1; j <= 9; j++) { - for (oid_t k = 1; k <= 9; k++) { - if (i != j && j != k && i != k) { - predicate_distribution.push_back(std::vector{i, j, k}); - } - } - } - } - - predicate_distribution_size = predicate_distribution.size(); -} - -static std::vector GetPredicate() { - if (state.variability_threshold >= predicate_distribution_size) { - LOG_ERROR("Don't have enough samples"); - exit(EXIT_FAILURE); - } - - auto sample = rand() % state.variability_threshold; - LOG_INFO("Predicate : %u", sample); - auto predicate = predicate_distribution[sample]; - return predicate; -} - -static int GetLowerBound() { - int tuple_count = state.scale_factor * state.tuples_per_tilegroup; - int predicate_offset = 0.1 * tuple_count; - - LOG_TRACE("Tuple count : %d", tuple_count); - - int lower_bound = predicate_offset; - return lower_bound; -} - -static int GetUpperBound() { - int tuple_count = state.scale_factor * state.tuples_per_tilegroup; - int selected_tuple_count = state.selectivity * tuple_count; - int predicate_offset = 0.1 * tuple_count; - - int upper_bound = predicate_offset + selected_tuple_count; - return upper_bound; -} - -static expression::AbstractExpression *CreateSimpleScanPredicate( - oid_t key_attr, ExpressionType expression_type, oid_t constant) { - // First, create tuple value expression. - oid_t left_tuple_idx = 0; - expression::AbstractExpression *tuple_value_expr_left = - expression::ExpressionUtil::TupleValueFactory(type::TypeId::INTEGER, - left_tuple_idx, key_attr); - - // Second, create constant value expression. - type::Value constant_value_left = - type::ValueFactory::GetIntegerValue(constant); - - expression::AbstractExpression *constant_value_expr_left = - expression::ExpressionUtil::ConstantValueFactory(constant_value_left); - - // Finally, link them together using an greater than expression. - expression::AbstractExpression *predicate = - expression::ExpressionUtil::ComparisonFactory( - expression_type, tuple_value_expr_left, constant_value_expr_left); - - return predicate; -} - -/** - * @brief Create the scan predicate given a set of attributes. The predicate - * will be attr >= LOWER_BOUND AND attr < UPPER_BOUND. - * LOWER_BOUND and UPPER_BOUND are determined by the selectivity config. - */ -static expression::AbstractExpression *CreateScanPredicate( - std::vector key_attrs) { - const int tuple_start_offset = GetLowerBound(); - const int tuple_end_offset = GetUpperBound(); - - LOG_TRACE("Lower bound : %d", tuple_start_offset); - LOG_TRACE("Upper bound : %d", tuple_end_offset); - - expression::AbstractExpression *predicate = nullptr; - - // Go over all key_attrs - for (auto key_attr : key_attrs) { - // ATTR >= LOWER_BOUND && < UPPER_BOUND - - auto left_predicate = CreateSimpleScanPredicate( - key_attr, ExpressionType::COMPARE_GREATERTHANOREQUALTO, - tuple_start_offset); - - auto right_predicate = CreateSimpleScanPredicate( - key_attr, ExpressionType::COMPARE_LESSTHAN, tuple_end_offset); - - expression::AbstractExpression *attr_predicate = - expression::ExpressionUtil::ConjunctionFactory( - ExpressionType::CONJUNCTION_AND, left_predicate, right_predicate); - - // Build complex predicate - if (predicate == nullptr) { - predicate = attr_predicate; - } else { - // Join predicate with given attribute predicate - predicate = expression::ExpressionUtil::ConjunctionFactory( - ExpressionType::CONJUNCTION_AND, predicate, attr_predicate); - } - } - - return predicate; -} - -static void CreateIndexScanPredicate(std::vector key_attrs, - std::vector &key_column_ids, - std::vector &expr_types, - std::vector &values) { - const int tuple_start_offset = GetLowerBound(); - const int tuple_end_offset = GetUpperBound(); - - // Go over all key_attrs - for (auto key_attr : key_attrs) { - key_column_ids.push_back(key_attr); - expr_types.push_back(ExpressionType::COMPARE_GREATERTHANOREQUALTO); - values.push_back(type::ValueFactory::GetIntegerValue(tuple_start_offset)); - - key_column_ids.push_back(key_attr); - expr_types.push_back(ExpressionType::COMPARE_LESSTHAN); - values.push_back(type::ValueFactory::GetIntegerValue(tuple_end_offset)); - } -} - -/** - * @brief Get the string for a list of oids. - */ -static inline std::string GetOidVectorString(const std::vector &oids) { - std::string oid_str = ""; - for (oid_t o : oids) { - oid_str += " " + std::to_string(o); - } - return oid_str; -} - -/** - * @brief Create a hybrid scan executor based on selected key columns. - * @param tuple_key_attrs The columns which the seq scan predicate is on. - * @param index_key_attrs The columns in the *index key tuple* which the index - * scan predicate is on. It should match the corresponding columns in - * \b tuple_key_columns. - * @param column_ids Column ids to be added to the result tile after scan. - * @return A hybrid scan executor based on the key columns. - */ -static std::shared_ptr CreateHybridScanPlan( - const std::vector &tuple_key_attrs, - const std::vector &index_key_attrs, - const std::vector &column_ids) { - // Create and set up seq scan executor - auto predicate = CreateScanPredicate(tuple_key_attrs); - - planner::IndexScanPlan::IndexScanDesc index_scan_desc; - - std::vector key_column_ids; - std::vector expr_types; - std::vector values; - std::vector runtime_keys; - - // Create index scan predicate - CreateIndexScanPredicate(index_key_attrs, key_column_ids, expr_types, values); - - // Determine hybrid scan type - auto hybrid_scan_type = HybridScanType::SEQUENTIAL; - - // Pick index - auto index = PickIndex(sdbench_table.get(), tuple_key_attrs); - - if (index != nullptr) { - index_scan_desc = planner::IndexScanPlan::IndexScanDesc( - index->GetOid(), key_column_ids, expr_types, values, runtime_keys); - - hybrid_scan_type = HybridScanType::HYBRID; - } - - LOG_TRACE("Hybrid scan type : %d", hybrid_scan_type); - - std::shared_ptr hybrid_scan_node( - new planner::HybridScanPlan(sdbench_table.get(), predicate, column_ids, - index_scan_desc, hybrid_scan_type)); - - return hybrid_scan_node; -} - -const static std::string OUTPUT_FILE = "outputfile.summary"; -std::ofstream out(OUTPUT_FILE); - -oid_t query_itr; - -double total_duration = 0; - -UNUSED_ATTRIBUTE static void WriteOutput(double duration) { - // Convert to ms - duration *= 1000; - - auto index_count = index_tuner.GetIndexCount(); - - // Write out output in verbose mode - if (state.verbose == true) { - LOG_INFO("----------------------------------------------------------"); - LOG_INFO("%d %d %.3lf %.3lf %u %.1lf %d %d %d %u :: %.1lf ms", - state.index_usage_type, state.query_complexity_type, - state.selectivity, state.projectivity, query_itr, - state.write_ratio, state.scale_factor, state.attribute_count, - state.tuples_per_tilegroup, index_count, duration); - } - - out << state.index_usage_type << " "; - out << state.query_complexity_type << " "; - out << state.selectivity << " "; - out << state.projectivity << " "; - out << query_itr << " "; - out << state.write_ratio << " "; - out << state.scale_factor << " "; - out << state.attribute_count << " "; - out << state.tuples_per_tilegroup << " "; - out << index_count << " "; - out << std::fixed << std::setprecision(2) << duration << "\n"; - - out.flush(); -} - -/** - * @brief Map the accsessed columns to a access bitmap. - * @details We should use the output of this method to construct a Sample for - * layout tuning instead of passing in the accessed columns directly!! - */ -static std::vector GetColumnsAccessed( - const std::vector &column_ids) { - std::vector columns_accessed; - std::map columns_accessed_map; - - // Init map - for (auto col : column_ids) columns_accessed_map[(int)col] = 1; - - for (oid_t column_itr = 0; column_itr < state.attribute_count + 1; - column_itr++) { - auto location = columns_accessed_map.find(column_itr); - auto end = columns_accessed_map.end(); - if (location != end) - columns_accessed.push_back(1); - else - columns_accessed.push_back(0); - } - - return columns_accessed; -} - -/** - * @brief Execute a set of executors and update access information. - * - * @param executors Executors to be executed. - * @param index_columns_accessed Columns that are accessed by index scan, used - * fpr index tuning. - * @param tuple_columns_accessed Columns of the tuples that are accessed, used - * for layout tuning. - * @param selectivity The selectivity of the operation. - */ -static void ExecuteTest(std::vector &executors, - tuning::SampleType sample_type, - std::vector> index_columns_accessed, - std::vector> tuple_columns_accessed, - UNUSED_ATTRIBUTE double selectivity) { - Timer<> timer; - - bool status = false; - - // Increment query counter - query_itr++; - - // Reset timer - timer.Reset(); - timer.Start(); - - // Run all the executors - for (auto executor : executors) { - status = executor->Init(); - if (status == false) { - throw Exception("Init failed"); - } - - std::vector> result_tiles; - - while (executor->Execute() == true) { - std::unique_ptr result_tile(executor->GetOutput()); - result_tiles.emplace_back(result_tile.release()); - } - - size_t sum = 0; - for (auto &result_tile : result_tiles) { - if (result_tile != nullptr) sum += result_tile->GetTupleCount(); - } - - LOG_TRACE("result tiles have %d tuples", (int)sum); - - // Execute stuff - executor->Execute(); - } - - // For holistic index - if (state.holistic_indexing) { - for (auto index_columns : index_columns_accessed) { - if (index_columns.size() == 3) { // It should be so for moderate query - oid_t i = oid_t(index_columns[0]); - oid_t j = oid_t(index_columns[1]); - oid_t k = oid_t(index_columns[2]); - if (!predicate_used[i][j][k]) { - // Copy the predicate column - CopyColumn(i); - CopyColumn(j); - CopyColumn(k); - predicate_used[i][j][k] = true; - } - } - } - } - - // Emit time - timer.Stop(); - auto duration = timer.GetDuration(); - total_duration += duration; - - WriteOutput(duration); - - // Record index sample - for (auto &index_columns : index_columns_accessed) { - tuning::Sample index_access_sample( - index_columns, duration / index_columns_accessed.size(), sample_type); - // ???, selectivity); - sdbench_table->RecordIndexSample(index_access_sample); - } - - // Record layout sample - for (auto &tuple_columns : tuple_columns_accessed) { - // Record layout sample - tuning::Sample tuple_access_bitmap( - GetColumnsAccessed(tuple_columns), - duration / tuple_columns_accessed.size()); - sdbench_table->RecordLayoutSample(tuple_access_bitmap); - } -} - -static std::shared_ptr PickIndex(storage::DataTable *table, - std::vector query_attrs) { - // Construct set - std::set query_attrs_set(query_attrs.begin(), query_attrs.end()); - - oid_t index_count = table->GetIndexCount(); - - // Empty index pointer - std::shared_ptr index; - - // Can't use indexes => return empty index - if (state.index_usage_type == INDEX_USAGE_TYPE_NEVER) { - return index; - } - - // Go over all indices - bool query_index_found = false; - oid_t index_itr = 0; - for (index_itr = 0; index_itr < index_count; index_itr++) { - auto index_attrs = table->GetIndexAttrs(index_itr); - - auto index = table->GetIndex(index_itr); - // Check if index exists - if (index == nullptr) { - continue; - } - - // Some attribute did not match - if (index_attrs != query_attrs_set) { - continue; - } - - // Can only use full indexes ? - if (state.index_usage_type == INDEX_USAGE_TYPE_FULL) { - auto indexed_tg_count = index->GetIndexedTileGroupOff(); - auto table_tg_count = table->GetTileGroupCount(); - - LOG_TRACE("Indexed TG Count : %lu", indexed_tg_count); - LOG_TRACE("Table TG Count : %lu", table_tg_count); - - if (indexed_tg_count < table_tg_count) { - continue; - } - } - - // Exact match - query_index_found = true; - break; - - // update index count - index_count = table->GetIndexCount(); - } - - // Found index - if (query_index_found == true) { - LOG_TRACE("Found available Index"); - index = table->GetIndex(index_itr); - } else { - LOG_TRACE("Did not find available index"); - } - - return index; -} - -/** - * @brief Copy a column from the table. - */ -static void CopyColumn(oid_t col_itr) { - auto tile_group_count = sdbench_table->GetTileGroupCount(); - for (oid_t tile_group_itr = 0; tile_group_itr < tile_group_count; - tile_group_itr++) { - // Prepare a tile for copying - std::vector columns; - - catalog::Column column1(type::TypeId::INTEGER, - type::Type::GetTypeSize(type::TypeId::INTEGER), "A", - true); - columns.push_back(column1); - - // Schema - catalog::Schema *schema = new catalog::Schema(columns); - - // Column Names - std::vector column_names; - - column_names.push_back("COL 1"); - - // TG Header - storage::TileGroupHeader *header = new storage::TileGroupHeader( - BackendType::MM, state.tuples_per_tilegroup); - - storage::Tile *new_tile = storage::TileFactory::GetTile( - BackendType::MM, INVALID_OID, INVALID_OID, INVALID_OID, INVALID_OID, - header, *schema, nullptr, state.tuples_per_tilegroup); - - // Begin copy - oid_t orig_tile_offset, orig_tile_column_offset; - auto orig_tile_group = sdbench_table->GetTileGroup(tile_group_itr); - auto orig_layout = orig_tile_group->GetLayout(); - orig_layout.LocateTileAndColumn(col_itr, orig_tile_offset, - orig_tile_column_offset); - auto orig_tile = orig_tile_group->GetTile(orig_tile_offset); - oid_t tuple_count = state.tuples_per_tilegroup; - for (oid_t tuple_itr = 0; tuple_itr < tuple_count; tuple_itr++) { - auto val = orig_tile->GetValue(tuple_itr, orig_tile_column_offset); - new_tile->SetValue(val, tuple_itr, 0); - } - - delete new_tile; - delete header; - delete schema; - } -} - -static void RunSimpleQuery() { - std::vector tuple_key_attrs; - std::vector index_key_attrs; - - oid_t predicate = rand() % state.variability_threshold; - oid_t first_attribute = predicate; - tuple_key_attrs = {first_attribute}; - index_key_attrs = {0}; - - // PHASE LENGTH - for (oid_t txn_itr = 0; txn_itr < state.phase_length; txn_itr++) { - AggregateQueryHelper(tuple_key_attrs, index_key_attrs); - } -} - -static void RunModerateQuery() { - LOG_TRACE("Moderate Query"); - - std::vector tuple_key_attrs; - std::vector index_key_attrs; - - auto predicate = GetPredicate(); - tuple_key_attrs = predicate; - index_key_attrs = {0, 1, 2}; - - LOG_TRACE("Moderate :: %s", GetOidVectorString(tuple_key_attrs).c_str()); - - // PHASE LENGTH - for (oid_t txn_itr = 0; txn_itr < state.phase_length; txn_itr++) { - AggregateQueryHelper(tuple_key_attrs, index_key_attrs); - } -} - -/** - * @brief Run complex query - * @details 60% join test, 30% moderate query, 10% simple query - */ -static void RunComplexQuery() { - LOG_TRACE("Complex Query"); - - std::vector left_table_tuple_key_attrs; - std::vector left_table_index_key_attrs; - std::vector right_table_tuple_key_attrs; - std::vector right_table_index_key_attrs; - oid_t left_table_join_column; - oid_t right_table_join_column; - - bool is_join_query = false; - bool is_aggregate_query = false; - - // Assume there are 20 columns, - // 10 for the left table, 10 for the right table - auto predicate = GetPredicate(); - left_table_tuple_key_attrs = predicate; - left_table_index_key_attrs = {0, 1, 2}; - std::vector tuple_key_attrs = predicate; - std::vector index_key_attrs = {0, 1, 2}; - right_table_tuple_key_attrs = {predicate[0] + 10, predicate[1] + 10, - predicate[2] + 10}; - right_table_index_key_attrs = {0, 1, 2}; - - predicate = GetPredicate(); - left_table_join_column = predicate[0]; - right_table_join_column = predicate[1]; - - // Pick join or aggregate - // is_join_query = true; - // is_aggregate_query = false; - auto sample = rand() % 10; - if (sample > 5) { - is_join_query = true; - is_aggregate_query = false; - } else { - is_aggregate_query = true; - is_join_query = false; - } - - if (is_join_query == true) { - LOG_INFO("Complex :: %s, %s, c1: %d, c2: %d", - GetOidVectorString(left_table_tuple_key_attrs).c_str(), - GetOidVectorString(right_table_tuple_key_attrs).c_str(), - (int)left_table_join_column, (int)right_table_join_column); - } else if (is_aggregate_query == true) { - LOG_TRACE("Complex :: %s", GetOidVectorString(tuple_key_attrs).c_str()); - } else { - LOG_ERROR("Invalid query \n"); - return; - } - - // PHASE LENGTH - for (oid_t txn_itr = 0; txn_itr < state.phase_length; txn_itr++) { - // Invoke appropriate query - if (is_join_query == true) { - JoinQueryHelper(left_table_tuple_key_attrs, left_table_index_key_attrs, - right_table_tuple_key_attrs, right_table_index_key_attrs, - left_table_join_column, right_table_join_column); - } else if (is_aggregate_query == true) { - AggregateQueryHelper(tuple_key_attrs, index_key_attrs); - } else { - LOG_ERROR("Invalid query \n"); - return; - } - } -} - -static void JoinQueryHelper( - const std::vector &left_table_tuple_key_attrs, - const std::vector &left_table_index_key_attrs, - const std::vector &right_table_tuple_key_attrs, - const std::vector &right_table_index_key_attrs, - const oid_t left_table_join_column, const oid_t right_table_join_column) { - LOG_TRACE("Run join query on left table: %s and right table: %s", - GetOidVectorString(left_table_tuple_key_attrs).c_str(), - GetOidVectorString(right_table_tuple_key_attrs).c_str()); - const bool is_inlined = true; - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - auto txn = txn_manager.BeginTransaction(); - - ///////////////////////////////////////////////////////// - // SEQ SCAN + PREDICATE - ///////////////////////////////////////////////////////// - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - // Column ids to be added to logical tile after scan. - // Left half of the columns are considered left table, - // right half of the columns are considered right table. - std::vector column_ids; - oid_t column_count = state.attribute_count; - - for (oid_t col_itr = 0; col_itr < column_count; col_itr++) { - column_ids.push_back(sdbench_column_ids[col_itr]); - } - - // Create and set up seq scan executor - auto left_table_scan_node = CreateHybridScanPlan( - left_table_tuple_key_attrs, left_table_index_key_attrs, column_ids); - auto right_table_scan_node = CreateHybridScanPlan( - right_table_tuple_key_attrs, right_table_index_key_attrs, column_ids); - - executor::HybridScanExecutor left_table_hybrid_scan_executor( - left_table_scan_node.get(), context.get()); - executor::HybridScanExecutor right_table_hybrid_scan_executor( - right_table_scan_node.get(), context.get()); - - ///////////////////////////////////////////////////////// - // JOIN EXECUTOR - ///////////////////////////////////////////////////////// - - auto join_type = JoinType::INNER; - - // Create join predicate - expression::TupleValueExpression *left_table_attr = - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, - left_table_join_column); - expression::TupleValueExpression *right_table_attr = - new expression::TupleValueExpression(type::TypeId::INTEGER, 1, - right_table_join_column); - - std::unique_ptr join_predicate( - new expression::ComparisonExpression(ExpressionType::COMPARE_LESSTHAN, - left_table_attr, right_table_attr)); - - std::unique_ptr project_info(nullptr); - std::shared_ptr schema(nullptr); - - planner::NestedLoopJoinPlan nested_loop_join_node( - join_type, std::move(join_predicate), std::move(project_info), schema, - {left_table_join_column}, {right_table_join_column}); - - // Run the nested loop join executor - executor::NestedLoopJoinExecutor nested_loop_join_executor( - &nested_loop_join_node, nullptr); - - // Construct the executor tree - nested_loop_join_executor.AddChild(&left_table_hybrid_scan_executor); - nested_loop_join_executor.AddChild(&right_table_hybrid_scan_executor); - - ///////////////////////////////////////////////////////// - // MATERIALIZE - ///////////////////////////////////////////////////////// - - // Create and set up materialization executor - // FIXME: this will always retreive all columns, projectivity is ignored - std::vector output_columns; - std::unordered_map old_to_new_cols; - oid_t join_column_count = column_count * 2; - for (oid_t col_itr = 0; col_itr < join_column_count; col_itr++) { - auto column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "" + std::to_string(col_itr), is_inlined); - output_columns.push_back(column); - - old_to_new_cols[col_itr] = col_itr; - } - - std::shared_ptr output_schema( - new catalog::Schema(output_columns)); - bool physify_flag = true; // is going to create a physical tile - planner::MaterializationPlan mat_node(old_to_new_cols, output_schema, - physify_flag); - - executor::MaterializationExecutor mat_executor(&mat_node, nullptr); - mat_executor.AddChild(&nested_loop_join_executor); - - ///////////////////////////////////////////////////////// - // EXECUTE - ///////////////////////////////////////////////////////// - - std::vector executors; - executors.push_back(&mat_executor); - - ///////////////////////////////////////////////////////// - // COLLECT STATS - ///////////////////////////////////////////////////////// - - std::vector left_table_index_columns_accessed( - left_table_tuple_key_attrs.begin(), left_table_tuple_key_attrs.end()); - std::vector right_table_index_columns_accessed( - right_table_tuple_key_attrs.begin(), right_table_tuple_key_attrs.end()); - - // Prepare tuple columns accessed - auto left_table_tuple_columns_accessed = left_table_tuple_key_attrs; - auto right_table_tuple_columns_accessed = right_table_tuple_key_attrs; - left_table_tuple_columns_accessed.push_back(left_table_join_column); - right_table_tuple_columns_accessed.push_back(right_table_join_column); - - auto selectivity = state.selectivity; - - ExecuteTest( - executors, tuning::SampleType::ACCESS, - {left_table_index_columns_accessed, right_table_index_columns_accessed}, - {left_table_tuple_columns_accessed, right_table_tuple_columns_accessed}, - selectivity); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - LOG_TRACE("commit successfully"); - } else { - LOG_TRACE("commit failed"); - } -} - -static void AggregateQueryHelper(const std::vector &tuple_key_attrs, - const std::vector &index_key_attrs) { - if (state.verbose) { - LOG_INFO("Run aggregate query on %s ", - GetOidVectorString(tuple_key_attrs).c_str()); - } - - const bool is_inlined = true; - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - auto txn = txn_manager.BeginTransaction(); - - ///////////////////////////////////////////////////////// - // SEQ SCAN + PREDICATE - ///////////////////////////////////////////////////////// - - // Column ids to be added to logical tile after scan. - // We need all columns because projection can require any column - std::vector column_ids; - oid_t column_count = state.attribute_count; - - column_ids.push_back(0); - for (oid_t col_itr = 0; col_itr < column_count; col_itr++) { - column_ids.push_back(sdbench_column_ids[col_itr]); - } - - column_count = state.projectivity * state.attribute_count; - column_ids.resize(column_count); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - auto hybrid_scan_node = - CreateHybridScanPlan(tuple_key_attrs, index_key_attrs, column_ids); - executor::HybridScanExecutor hybrid_scan_executor(hybrid_scan_node.get(), - context.get()); - - ///////////////////////////////////////////////////////// - // AGGREGATION - ///////////////////////////////////////////////////////// - - // Resize column ids to contain only columns - // over which we compute aggregates - - // (1-5) Setup plan node - - // 1) Set up group-by columns - std::vector group_by_columns; - - // 2) Set up project info - DirectMapList direct_map_list; - oid_t col_itr = 0; - oid_t tuple_idx = 1; // tuple2 - for (col_itr = 0; col_itr < column_count; col_itr++) { - direct_map_list.push_back({col_itr, {tuple_idx, col_itr}}); - } - - std::unique_ptr proj_info( - new planner::ProjectInfo(TargetList(), std::move(direct_map_list))); - - // 3) Set up aggregates - std::vector agg_terms; - for (col_itr = 0; col_itr < column_count; col_itr++) { - planner::AggregatePlan::AggTerm max_column_agg( - ExpressionType::AGGREGATE_MAX, - expression::ExpressionUtil::TupleValueFactory(type::TypeId::INTEGER, 0, - col_itr), - false); - agg_terms.push_back(max_column_agg); - } - - // 4) Set up predicate (empty) - std::unique_ptr aggregate_predicate( - nullptr); - - // 5) Create output table schema - auto data_table_schema = sdbench_table->GetSchema(); - std::vector columns; - for (auto column_id : column_ids) { - columns.push_back(data_table_schema->GetColumn(column_id)); - } - - std::shared_ptr output_table_schema( - new catalog::Schema(columns)); - - // OK) Create the plan node - planner::AggregatePlan aggregation_node( - std::move(proj_info), std::move(aggregate_predicate), - std::move(agg_terms), std::move(group_by_columns), output_table_schema, - AggregateType::PLAIN); - - executor::AggregateExecutor aggregation_executor(&aggregation_node, - context.get()); - - aggregation_executor.AddChild(&hybrid_scan_executor); - - ///////////////////////////////////////////////////////// - // MATERIALIZE - ///////////////////////////////////////////////////////// - - // Create and set up materialization executor - std::vector output_columns; - std::unordered_map old_to_new_cols; - col_itr = 0; - for (auto column_id : column_ids) { - auto column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - std::to_string(column_id), is_inlined); - output_columns.push_back(column); - - old_to_new_cols[col_itr] = col_itr; - - col_itr++; - } - - std::shared_ptr output_schema( - new catalog::Schema(output_columns)); - bool physify_flag = true; // is going to create a physical tile - planner::MaterializationPlan mat_node(old_to_new_cols, output_schema, - physify_flag); - - executor::MaterializationExecutor mat_executor(&mat_node, nullptr); - - mat_executor.AddChild(&aggregation_executor); - - ///////////////////////////////////////////////////////// - // EXECUTE - ///////////////////////////////////////////////////////// - - std::vector executors; - executors.push_back(&mat_executor); - - ///////////////////////////////////////////////////////// - // COLLECT STATS - ///////////////////////////////////////////////////////// - std::vector index_columns_accessed(tuple_key_attrs.begin(), - tuple_key_attrs.end()); - auto selectivity = state.selectivity; - - auto tuple_columns_accessed = tuple_key_attrs; - for (auto column_id : column_ids) { - tuple_columns_accessed.push_back(column_id); - } - - ExecuteTest(executors, tuning::SampleType::ACCESS, {index_columns_accessed}, - {tuple_columns_accessed}, selectivity); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - LOG_TRACE("commit successfully"); - } else { - LOG_TRACE("commit failed"); - } -} - -/** - * @brief Run write transactions - * - * @param tuple_key_attrs Tuple attributes to query on. - * @param index_key_attrs Index attributes to query on. - * @param update_attrs Columns to be updated. The value value of each attribute - * in update_attrs will be updated to -v, where v is the original value, and -v - * is minus original value. - */ -static void UpdateHelper(const std::vector &tuple_key_attrs, - const std::vector &index_key_attrs, - const std::vector &update_attrs) { - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto txn = txn_manager.BeginTransaction(); - - ////////////////////////////////////////// - // SCAN + PREDICATE - ////////////////////////////////////////// - - std::vector column_ids; - oid_t column_count = state.attribute_count; - - column_ids.push_back(0); - for (oid_t col_itr = 0; col_itr < column_count; col_itr++) { - column_ids.push_back(col_itr); - } - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - auto hybrid_scan_node = - CreateHybridScanPlan(tuple_key_attrs, index_key_attrs, column_ids); - executor::HybridScanExecutor hybrid_scan_executor(hybrid_scan_node.get(), - context.get()); - - ////////////////////////////////////////// - // UPDATE - ////////////////////////////////////////// - - // Update the value of each attribute in update_attrs to -v, where v is the - // original value, and -v is minus original value. - - std::vector values; - TargetList target_list; - DirectMapList direct_map_list; - - target_list.clear(); - direct_map_list.clear(); - - // Build target_list: -value for update_attrs - for (oid_t update_attr : update_attrs) { - auto tuple_value_expression = new expression::TupleValueExpression( - type::TypeId::INTEGER, 0, update_attr); - auto minus_value_expression = - new expression::OperatorUnaryMinusExpression(tuple_value_expression); - planner::DerivedAttribute attribute{minus_value_expression}; - target_list.emplace_back(update_attr, attribute); - } - - // Build direct_map_list: value unchanged for other attributes - oid_t update_attr_itr = 0; - for (oid_t col_itr = 0; col_itr < column_count; col_itr++) { - // Skip the updated column - if (update_attr_itr > update_attrs.size() || - col_itr != update_attrs[update_attr_itr]) { - direct_map_list.emplace_back(col_itr, - std::pair(0, col_itr)); - } else { - update_attr_itr++; - } - } - - std::unique_ptr project_info( - new planner::ProjectInfo(std::move(target_list), - std::move(direct_map_list))); - planner::UpdatePlan update_node(sdbench_table.get(), std::move(project_info)); - - executor::UpdateExecutor update_executor(&update_node, context.get()); - update_executor.AddChild(&hybrid_scan_executor); - - ///////////////////////////////////////////////////////// - // EXECUTE - ///////////////////////////////////////////////////////// - - std::vector executors; - executors.push_back(&update_executor); - - ///////////////////////////////////////////////////////// - // COLLECT STATS - ///////////////////////////////////////////////////////// - std::vector index_columns_accessed(tuple_key_attrs.begin(), - tuple_key_attrs.end()); - auto selectivity = state.selectivity; - - auto tuple_columns_accessed = tuple_key_attrs; - for (oid_t update_attr : update_attrs) { - tuple_columns_accessed.push_back(update_attr); - } - - ExecuteTest(executors, tuning::SampleType::ACCESS, {index_columns_accessed}, - {tuple_columns_accessed}, selectivity); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - LOG_TRACE("commit successfully"); - } else { - LOG_TRACE("commit failed"); - } -} - -static void InsertHelper() { - const int BULK_INSERT_COUNT = 1000; - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - auto txn = txn_manager.BeginTransaction(); - - ///////////////////////////////////////////////////////// - // INSERT - ///////////////////////////////////////////////////////// - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - std::vector values; - type::Value insert_val = - type::ValueFactory::GetIntegerValue(++sdbench_tuple_counter); - TargetList target_list; - DirectMapList direct_map_list; - std::vector column_ids; - - target_list.clear(); - direct_map_list.clear(); - - for (oid_t col_id = 0; col_id <= state.attribute_count; col_id++) { - auto expression = - expression::ExpressionUtil::ConstantValueFactory(insert_val); - planner::DerivedAttribute attribute{expression}; - target_list.emplace_back(col_id, attribute); - column_ids.push_back(col_id); - } - - std::unique_ptr project_info( - new planner::ProjectInfo(std::move(target_list), - std::move(direct_map_list))); - - LOG_TRACE("Bulk insert count : %d", BULK_INSERT_COUNT); - planner::InsertPlan insert_node(sdbench_table.get(), std::move(project_info), - BULK_INSERT_COUNT); - executor::InsertExecutor insert_executor(&insert_node, context.get()); - - ///////////////////////////////////////////////////////// - // EXECUTE - ///////////////////////////////////////////////////////// - - std::vector executors; - executors.push_back(&insert_executor); - - ///////////////////////////////////////////////////////// - // COLLECT STATS - ///////////////////////////////////////////////////////// - std::vector index_columns_accessed; - double selectivity = 0; - - ExecuteTest(executors, tuning::SampleType::UPDATE, {{}}, {}, selectivity); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - LOG_TRACE("commit successfully"); - } else { - LOG_TRACE("commit failed"); - } -} - -/** - * @brief Run bulk insert workload. - */ -static void RunInsert() { - LOG_TRACE("Run insert"); - - for (oid_t txn_itr = 0; txn_itr < state.phase_length; txn_itr++) { - InsertHelper(); - } -} - -static void RunSimpleUpdate() { - std::vector tuple_key_attrs; - std::vector index_key_attrs; - std::vector update_attrs; - - update_attrs = {15, 16, 17}; - - oid_t predicate = rand() % state.variability_threshold; - oid_t first_attribute = predicate; - tuple_key_attrs = {first_attribute}; - index_key_attrs = {0}; - - UNUSED_ATTRIBUTE std::stringstream os; - os << "Simple Update :: "; - for (auto tuple_key_attr : tuple_key_attrs) { - os << tuple_key_attr << " "; - } - if (state.verbose) { - LOG_INFO("%s", os.str().c_str()); - } - - // PHASE LENGTH - for (oid_t txn_itr = 0; txn_itr < state.phase_length; txn_itr++) { - UpdateHelper(tuple_key_attrs, index_key_attrs, update_attrs); - } -} - -static void RunComplexUpdate() { - std::vector tuple_key_attrs; - std::vector index_key_attrs; - std::vector update_attrs; - - update_attrs = {15, 16, 17}; - - auto predicate = GetPredicate(); - tuple_key_attrs = predicate; - index_key_attrs = {0, 1, 2}; - - UNUSED_ATTRIBUTE std::stringstream os; - os << "Complex Update :: "; - for (auto tuple_key_attr : tuple_key_attrs) { - os << tuple_key_attr << " "; - } - LOG_TRACE("%s", os.str().c_str()); - - // PHASE LENGTH - for (oid_t txn_itr = 0; txn_itr < state.phase_length; txn_itr++) { - UpdateHelper(tuple_key_attrs, index_key_attrs, update_attrs); - } -} - -/** - * @brief Run query depending on query type - */ -static void RunQuery() { - LOG_TRACE("Run query"); - switch (state.query_complexity_type) { - case QUERY_COMPLEXITY_TYPE_SIMPLE: - RunSimpleQuery(); - break; - case QUERY_COMPLEXITY_TYPE_MODERATE: - RunModerateQuery(); - break; - case QUERY_COMPLEXITY_TYPE_COMPLEX: - RunComplexQuery(); - break; - default: - break; - } -} - -/** - * @brief Run write txn depending on write type - */ -static void RunWrite() { - LOG_TRACE("Run write"); - switch (state.write_complexity_type) { - case WRITE_COMPLEXITY_TYPE_SIMPLE: - RunSimpleUpdate(); - break; - case WRITE_COMPLEXITY_TYPE_COMPLEX: - RunComplexUpdate(); - break; - case WRITE_COMPLEXITY_TYPE_INSERT: - RunInsert(); - break; - default: - break; - } -} - -/** - * @brief A data structure to hold index information of a table. - */ -struct IndexSummary { - // Index oids - std::vector index_oids; - - // Index has complete built? - bool completed; -}; - -static size_t stable_index_configuration_op_count = 0; - -/** - * @brief Check if index scheme has converged. - * Determine by looking at how many times index has not been changed. - * - * @return true if the index configuration has converged. False otherwise. - */ -static bool HasIndexConfigurationConverged() { - static IndexSummary prev_index_summary; - // If the index configuration stays the same - // for "convergence_query_threshold" continuous queries, - // then it's considered as converged. - - IndexSummary index_summary; - index_summary.completed = true; - - // Get index summary - oid_t index_count = sdbench_table->GetIndexCount(); - auto table_tile_group_count = sdbench_table->GetTileGroupCount(); - for (oid_t index_itr = 0; index_itr < index_count; index_itr++) { - // Get index - auto index = sdbench_table->GetIndex(index_itr); - if (index == nullptr) { - continue; - } - - auto indexed_tile_group_offset = index->GetIndexedTileGroupOff(); - - // Get percentage completion - double fraction = 0.0; - if (table_tile_group_count != 0) { - fraction = - (double)indexed_tile_group_offset / (double)table_tile_group_count; - fraction *= 100; - } - - if (fraction < 0) { - index_summary.completed = false; - } - - // Get index columns - index_summary.index_oids.push_back(index->GetOid()); - } - - if (index_summary.completed == false) { - prev_index_summary = index_summary; - stable_index_configuration_op_count = 0; - return false; - } - - // Check if the index summary is the same - bool identical = true; - if (index_summary.index_oids.size() == prev_index_summary.index_oids.size()) { - for (size_t i = 0; i < index_summary.index_oids.size(); i++) { - if (index_summary.index_oids[i] != prev_index_summary.index_oids[i]) { - identical = false; - break; - } - } - } else { - identical = false; - } - - // Update index unchanged phase count - if (identical) { - stable_index_configuration_op_count += 1; - } else { - stable_index_configuration_op_count = 0; - } - - prev_index_summary = index_summary; - - // Check threshold # of ops - if (stable_index_configuration_op_count >= state.convergence_op_threshold) { - LOG_INFO("Has converged"); - return true; - } - - return false; -} - -/** - * @brief Do any preparation before running a benchmark. - */ -void BenchmarkPrepare() { - // Setup index tuner - index_tuner.SetAnalyzeSampleCountThreshold( - state.analyze_sample_count_threshold); - index_tuner.SetTileGroupsIndexedPerIteration( - state.tile_groups_indexed_per_iteration); - index_tuner.SetDurationBetweenPauses(state.duration_between_pauses); - index_tuner.SetDurationOfPause(state.duration_of_pause); - index_tuner.SetAnalyzeSampleCountThreshold( - state.analyze_sample_count_threshold); - index_tuner.SetTileGroupsIndexedPerIteration( - state.tile_groups_indexed_per_iteration); - index_tuner.SetIndexUtilityThreshold(state.index_utility_threshold); - index_tuner.SetIndexCountThreshold(state.index_count_threshold); - index_tuner.SetWriteRatioThreshold(state.write_ratio_threshold); - index_tuner.SetTileGroupsIndexedPerIteration( - state.tile_groups_indexed_per_iteration); - - // seed generator - srand(generator_seed); - - // Generate sequence - GenerateSequence(state.attribute_count); - - // Generate distribution - GeneratePredicateDistribution(); - - CreateAndLoadTable((LayoutType)state.layout_mode); - - // Start index tuner - if (state.index_usage_type != INDEX_USAGE_TYPE_NEVER) { - index_tuner.AddTable(sdbench_table.get()); - - // Start after adding tables - index_tuner.Start(); - } - - // Start layout tuner - if (state.layout_mode == LayoutType::HYBRID) { - layout_tuner.AddTable(sdbench_table.get()); - - // Start layout tuner - layout_tuner.Start(); - } -} - -/** - * @brief Do any clean up after running a benchmark. - */ -void BenchmarkCleanUp() { - // Stop index tuner - if (state.index_usage_type != INDEX_USAGE_TYPE_NEVER) { - index_tuner.Stop(); - index_tuner.ClearTables(); - } - - if (state.layout_mode == LayoutType::HYBRID) { - layout_tuner.Stop(); - layout_tuner.ClearTables(); - } - - // Drop Indexes - DropIndexes(); - - // Reset - query_itr = 0; - - out.close(); -} - -static void SDBenchHelper() { - double write_ratio = state.write_ratio; - - // Reset total duration - total_duration = 0; - - // Reset query counter - query_itr = 0; - - Timer<> index_unchanged_timer; - - // cache original phase length - size_t original_phase_length = state.phase_length; - if (original_phase_length < 5) { - LOG_ERROR("Phase length must be greater than 5"); - return; - } - - // run desired number of ops - oid_t phase_count = 0; - for (oid_t op_itr = 0; op_itr < state.total_ops;) { - // set phase length (NOTE: uneven across phases) - size_t minimum_op_count = (original_phase_length / 5); - size_t rest_op_count = original_phase_length - minimum_op_count; - size_t current_phase_length = minimum_op_count + rand() % rest_op_count; - if (current_phase_length > state.total_ops - op_itr) { - current_phase_length = state.total_ops - op_itr; - } - - state.phase_length = current_phase_length; - op_itr += current_phase_length; - phase_count++; - - double rand_sample = (double)rand() / RAND_MAX; - - // Do write - if (rand_sample < write_ratio) { - RunWrite(); - } - // Do read - else { - RunQuery(); - } - - // Randomly add some access sample to build indices - if (state.holistic_indexing && state.multi_stage_idx == 1) { - auto predicate = GetPredicate(); - std::vector index_columns_accessed(predicate.begin(), - predicate.end()); - // double selectivity = state.selectivity; - double duration = rand() % 100; - tuning::Sample index_access_sample(index_columns_accessed, duration, - tuning::SampleType::ACCESS); - // ??? , selectivity); - for (oid_t i = 0; i < state.analyze_sample_count_threshold; i++) { - sdbench_table->RecordIndexSample(index_access_sample); - } - } - - // Check index convergence - if (state.convergence == true) { - bool converged = HasIndexConfigurationConverged(); - if (converged == true) { - break; - } - } - } - - LOG_INFO("Average phase length : %.0lf", - (double)state.total_ops / phase_count); - LOG_INFO("Duration : %.2lf", total_duration); -} - -void RunMultiStageBenchmark() { - BenchmarkPrepare(); - - int orig_analyze_sample_count_threshold = - state.analyze_sample_count_threshold; - // The first stage - if (state.holistic_indexing) { - // Make the index build speed faster - index_tuner.SetAnalyzeSampleCountThreshold( - (int)(orig_analyze_sample_count_threshold * 0.6)); - } - state.multi_stage_idx = 0; - SDBenchHelper(); - // The second stage - if (state.holistic_indexing) { - // Make the index build speed slower - index_tuner.SetAnalyzeSampleCountThreshold( - (int)(orig_analyze_sample_count_threshold * 2)); - } - state.multi_stage_idx = 1; - SDBenchHelper(); - // The third stage - state.write_ratio = 1.00; - state.multi_stage_idx = 2; - if (state.holistic_indexing) { - // Holistic doesn't drop index - index_tuner.SetAnalyzeSampleCountThreshold( - (int)(orig_analyze_sample_count_threshold)); - index_tuner.SetWriteRatioThreshold(1.0); - } - SDBenchHelper(); - - BenchmarkCleanUp(); -} - -void RunSDBenchTest() { - BenchmarkPrepare(); - - // Run the benchmark once - SDBenchHelper(); - - BenchmarkCleanUp(); -} - -} // namespace sdbench -} // namespace benchmark -} // namespace peloton diff --git a/src/main/tpcc/tpcc.cpp b/src/main/tpcc/tpcc.cpp deleted file mode 100644 index 5d9af1a28be..00000000000 --- a/src/main/tpcc/tpcc.cpp +++ /dev/null @@ -1,103 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc.cpp -// -// Identification: src/main/tpcc/tpcc.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include - -#include "common/logger.h" -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_workload.h" - -#include "gc/gc_manager_factory.h" -#include "concurrency/epoch_manager_factory.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -configuration state; - -// Main Entry Point -void RunBenchmark() { - - if (state.gc_mode == false) { - gc::GCManagerFactory::Configure(0); - } else { - gc::GCManagerFactory::Configure(state.gc_backend_count); - } - - concurrency::EpochManagerFactory::Configure(state.epoch); - - std::unique_ptr epoch_thread; - std::vector> gc_threads; - - concurrency::EpochManager &epoch_manager = concurrency::EpochManagerFactory::GetInstance(); - - if (concurrency::EpochManagerFactory::GetEpochType() == EpochType::DECENTRALIZED_EPOCH) { - for (size_t i = 0; i < (size_t) state.backend_count; ++i) { - // register thread to epoch manager - epoch_manager.RegisterThread(i); - } - } - - // start epoch. - epoch_manager.StartEpoch(epoch_thread); - - gc::GCManager &gc_manager = gc::GCManagerFactory::GetInstance(); - - // start GC. - gc_manager.StartGC(gc_threads); - - // Create the database - CreateTPCCDatabase(); - - // Load the database - LoadTPCCDatabase(); - - // Run the workload - RunWorkload(); - - // stop GC. - gc_manager.StopGC(); - - // stop epoch. - epoch_manager.StopEpoch(); - - // join all gc threads - for (auto &gc_thread : gc_threads) { - PELOTON_ASSERT(gc_thread != nullptr); - gc_thread->join(); - } - - // join epoch thread - PELOTON_ASSERT(epoch_thread != nullptr); - epoch_thread->join(); - - - // Emit throughput - WriteOutput(); -} - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton - -int main(int argc, char **argv) { - peloton::benchmark::tpcc::ParseArguments(argc, argv, - peloton::benchmark::tpcc::state); - - peloton::benchmark::tpcc::RunBenchmark(); - - return 0; -} diff --git a/src/main/tpcc/tpcc_configuration.cpp b/src/main/tpcc/tpcc_configuration.cpp deleted file mode 100644 index 3cd63cbf7da..00000000000 --- a/src/main/tpcc/tpcc_configuration.cpp +++ /dev/null @@ -1,271 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_configuration.cpp -// -// Identification: src/main/tpcc/tpcc_configuration.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#include -#include -#include - -#include "benchmark/tpcc/tpcc_configuration.h" -#include "common/logger.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -void Usage(FILE *out) { - fprintf(out, - "Command line options : tpcc \n" - " -h --help : print help message \n" - " -i --index : index type: bwtree (default) \n" - " -k --scale_factor : scale factor \n" - " -d --duration : execution duration \n" - " -p --profile_duration : profile duration \n" - " -b --backend_count : # of backends \n" - " -w --warehouse_count : # of warehouses \n" - " -e --exp_backoff : enable exponential backoff \n" - " -a --affinity : enable client affinity \n" - " -g --gc_mode : enable garbage collection \n" - " -n --gc_backend_count : # of gc backends \n" - " -l --loader_count : # of loaders \n" - " -y --epoch : epoch type: centralized or decentralized \n" - ); -} - -static struct option opts[] = { - { "index", optional_argument, NULL, 'i' }, - { "scale_factor", optional_argument, NULL, 'k' }, - { "duration", optional_argument, NULL, 'd' }, - { "profile_duration", optional_argument, NULL, 'p' }, - { "backend_count", optional_argument, NULL, 'b' }, - { "warehouse_count", optional_argument, NULL, 'w' }, - { "exp_backoff", no_argument, NULL, 'e' }, - { "affinity", no_argument, NULL, 'a' }, - { "gc_mode", no_argument, NULL, 'g' }, - { "gc_backend_count", optional_argument, NULL, 'n' }, - { "loader_count", optional_argument, NULL, 'n' }, - { "epoch", optional_argument, NULL, 'y' }, - { NULL, 0, NULL, 0 } -}; - -void ValidateIndex(const configuration &state) { - if (state.index != IndexType::BWTREE) { - LOG_ERROR("Invalid index"); - exit(EXIT_FAILURE); - } -} - -void ValidateScaleFactor(const configuration &state) { - if (state.scale_factor <= 0) { - LOG_ERROR("Invalid scale_factor :: %lf", state.scale_factor); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "scale_factor", state.scale_factor); -} - -void ValidateDuration(const configuration &state) { - if (state.duration <= 0) { - LOG_ERROR("Invalid duration :: %lf", state.duration); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "duration", state.duration); -} - -void ValidateProfileDuration(const configuration &state) { - if (state.profile_duration <= 0) { - LOG_ERROR("Invalid profile_duration :: %lf", state.profile_duration); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "profile_duration", state.profile_duration); -} - -void ValidateBackendCount(const configuration &state) { - if (state.backend_count <= 0) { - LOG_ERROR("Invalid backend_count :: %d", state.backend_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "backend_count", state.backend_count); -} - -void ValidateWarehouseCount(const configuration &state) { - if (state.warehouse_count <= 0) { - LOG_ERROR("Invalid warehouse_count :: %d", state.warehouse_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "warehouse_count", state.warehouse_count); -} - -void ValidateGCBackendCount(const configuration &state) { - if (state.gc_backend_count <= 0) { - LOG_ERROR("Invalid gc_backend_count :: %d", state.gc_backend_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "gc_backend_count", state.gc_backend_count); -} - - -void ParseArguments(int argc, char *argv[], configuration &state) { - // Default Values - state.index = IndexType::BWTREE; - state.epoch = EpochType::DECENTRALIZED_EPOCH; - state.scale_factor = 1; - state.duration = 10; - state.profile_duration = 1; - state.backend_count = 2; - state.warehouse_count = 2; - state.exp_backoff = false; - state.affinity = false; - state.gc_mode = false; - state.gc_backend_count = 1; - state.loader_count = 1; - - - // Parse args - while (1) { - int idx = 0; - int c = getopt_long(argc, argv, "heagi:k:d:p:b:w:n:l:y:", opts, &idx); - - if (c == -1) break; - - switch (c) { - case 'i': { - char *index = optarg; - if (strcmp(index, "bwtree") == 0) { - state.index = IndexType::BWTREE; - } else { - LOG_ERROR("Unknown index: %s", index); - exit(EXIT_FAILURE); - } - break; - } - case 'y': { - char *epoch = optarg; - if (strcmp(epoch, "decentralized") == 0) { - state.epoch = EpochType::DECENTRALIZED_EPOCH; - } else { - LOG_ERROR("Unknown epoch: %s", epoch); - exit(EXIT_FAILURE); - } - break; - } - case 'l': - state.loader_count = atoi(optarg); - break; - case 'k': - state.scale_factor = atof(optarg); - break; - case 'd': - state.duration = atof(optarg); - break; - case 'p': - state.profile_duration = atof(optarg); - break; - case 'b': - state.backend_count = atoi(optarg); - break; - case 'w': - state.warehouse_count = atoi(optarg); - break; - case 'e': - state.exp_backoff = true; - break; - case 'a': - state.affinity = true; - break; - case 'g': - state.gc_mode = true; - break; - case 'n': - state.gc_backend_count = atoi(optarg); - break; - - case 'h': - Usage(stderr); - exit(EXIT_FAILURE); - break; - - default: - LOG_ERROR("Unknown option: -%c-", c); - Usage(stderr); - exit(EXIT_FAILURE); - } - } - - // Static TPCC parameters - state.item_count = 100000 * state.scale_factor; - state.districts_per_warehouse = 10; - state.customers_per_district = 3000 * state.scale_factor; - state.new_orders_per_district = 900 * state.scale_factor; - - // Print configuration - ValidateIndex(state); - ValidateScaleFactor(state); - ValidateDuration(state); - ValidateProfileDuration(state); - ValidateBackendCount(state); - ValidateWarehouseCount(state); - ValidateGCBackendCount(state); - - LOG_TRACE("%s : %d", "Run client affinity", state.affinity); - LOG_TRACE("%s : %d", "Run exponential backoff", state.exp_backoff); - LOG_TRACE("%s : %d", "Run garbage collection", state.gc_mode); -} - - - -void WriteOutput() { - std::ofstream out("outputfile.summary"); - - oid_t total_profile_memory = 0; - for (auto &entry : state.profile_memory) { - total_profile_memory += entry; - } - - LOG_INFO("----------------------------------------------------------"); - LOG_INFO("%lf %d %d :: %lf %lf %d", - state.scale_factor, - state.backend_count, - state.warehouse_count, - state.throughput, - state.abort_rate, - total_profile_memory); - - out << state.scale_factor << " "; - out << state.backend_count << " "; - out << state.warehouse_count << " "; - out << state.throughput << " "; - out << state.abort_rate << " "; - out << total_profile_memory << "\n"; - - for (size_t round_id = 0; round_id < state.profile_throughput.size(); - ++round_id) { - out << "[" << std::setw(3) << std::left - << state.profile_duration * round_id << " - " << std::setw(3) - << std::left << state.profile_duration * (round_id + 1) - << " s]: " << state.profile_throughput[round_id] << " " - << state.profile_abort_rate[round_id] << " " - << state.profile_memory[round_id] << "\n"; - } - out.flush(); - out.close(); -} - - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton diff --git a/src/main/tpcc/tpcc_delivery.cpp b/src/main/tpcc/tpcc_delivery.cpp deleted file mode 100644 index 8b688e1a4c2..00000000000 --- a/src/main/tpcc/tpcc_delivery.cpp +++ /dev/null @@ -1,572 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_payment.cpp -// -// Identification: src/main/tpcc/tpcc_delivery.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_workload.h" - -#include "catalog/column.h" -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/generator.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/timer.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/aggregate_executor.h" -#include "executor/delete_executor.h" -#include "executor/executor_context.h" -#include "executor/index_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/limit_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/update_executor.h" - -#include "common/container_tuple.h" -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/tuple_value_expression.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/aggregate_plan.h" -#include "planner/delete_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/limit_plan.h" -#include "planner/materialization_plan.h" -#include "planner/project_info.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -bool RunDelivery(const size_t &thread_id) { - /* - "DELIVERY": { - "getNewOrder": "SELECT NO_O_ID FROM NEW_ORDER WHERE NO_D_ID = ? AND NO_W_ID = - ? AND NO_O_ID > -1 LIMIT 1", # - "deleteNewOrder": "DELETE FROM NEW_ORDER WHERE NO_D_ID = ? AND NO_W_ID = ? - AND NO_O_ID = ?", # d_id, w_id, no_o_id - "getCId": "SELECT O_C_ID FROM ORDERS WHERE O_ID = ? AND O_D_ID = ? AND O_W_ID - = ?", # no_o_id, d_id, w_id - "updateOrders": "UPDATE ORDERS SET O_CARRIER_ID = ? WHERE O_ID = ? AND O_D_ID - = ? AND O_W_ID = ?", # o_carrier_id, no_o_id, d_id, w_id - "updateOrderLine": "UPDATE ORDER_LINE SET OL_DELIVERY_D = ? WHERE OL_O_ID = ? - AND OL_D_ID = ? AND OL_W_ID = ?", # o_entry_d, no_o_id, d_id, w_id - "sumOLAmount": "SELECT SUM(OL_AMOUNT) FROM ORDER_LINE WHERE OL_O_ID = ? AND - OL_D_ID = ? AND OL_W_ID = ?", # no_o_id, d_id, w_id - "updateCustomer": "UPDATE CUSTOMER SET C_BALANCE = C_BALANCE + ? WHERE C_ID = - ? AND C_D_ID = ? AND C_W_ID = ?", # ol_total, c_id, d_id, w_id - } - */ - - LOG_TRACE("-------------------------------------"); - - ///////////////////////////////////////////////////////// - // PREPARE ARGUMENTS - ///////////////////////////////////////////////////////// - int warehouse_id = GenerateWarehouseId(thread_id); - int o_carrier_id = - GetRandomInteger(orders_min_carrier_id, orders_max_carrier_id); - - std::vector runtime_keys; - - ///////////////////////////////////////////////////////// - // BEGIN TRANSACTION - ///////////////////////////////////////////////////////// - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - auto txn = txn_manager.BeginTransaction(thread_id); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - for (int d_id = 0; d_id < state.districts_per_warehouse; ++d_id) { - LOG_TRACE( - "getNewOrder: SELECT NO_O_ID FROM NEW_ORDER WHERE NO_D_ID = ? AND " - "NO_W_ID = ? AND NO_O_ID > -1 LIMIT 1"); - - // Construct index scan executor - std::vector new_order_column_ids = {COL_IDX_NO_O_ID}; - std::vector new_order_key_column_ids = { - COL_IDX_NO_D_ID, COL_IDX_NO_W_ID, COL_IDX_NO_O_ID}; - - std::vector new_order_expr_types; - - new_order_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - new_order_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - new_order_expr_types.push_back(ExpressionType::COMPARE_GREATERTHAN); - - std::vector new_order_key_values; - - new_order_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - new_order_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - new_order_key_values.push_back( - type::ValueFactory::GetIntegerValue(-1).Copy()); - - planner::IndexScanPlan::IndexScanDesc new_order_idex_scan_desc( - new_order_table_pkey_index_oid, new_order_key_column_ids, - new_order_expr_types, new_order_key_values, runtime_keys); - - planner::IndexScanPlan new_order_idex_scan_node(new_order_table, nullptr, - new_order_column_ids, - new_order_idex_scan_desc); - - executor::IndexScanExecutor new_order_index_scan_executor( - &new_order_idex_scan_node, context.get()); - - // Construct limit executor - size_t limit = 1; - size_t offset = 0; - planner::LimitPlan limit_node(limit, offset); - executor::LimitExecutor limit_executor(&limit_node, context.get()); - limit_executor.AddChild(&new_order_index_scan_executor); - - auto new_order_ids = ExecuteRead(&limit_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (new_order_ids.size() == 0) { - // TODO: No orders for this district: skip it. Note: This must be - // reported if > 1% - continue; - } - - assert(new_order_ids.size() == 1); - assert(new_order_ids[0].size() == 1); - - // result: NO_O_ID - auto no_o_id = new_order_ids[0][0]; - - LOG_TRACE("no_o_id = %d", type::ValuePeeker::PeekInteger(no_o_id)); - - LOG_TRACE( - "getCId: SELECT O_C_ID FROM ORDERS WHERE O_ID = ? AND O_D_ID = ? AND " - "O_W_ID = ?"); - - std::vector orders_column_ids = {COL_IDX_O_C_ID}; - std::vector orders_key_column_ids = {COL_IDX_O_ID, COL_IDX_O_D_ID, - COL_IDX_O_W_ID}; - - std::vector orders_expr_types; - - orders_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - orders_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - orders_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector orders_key_values; - - orders_key_values.push_back(no_o_id); - orders_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - orders_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc orders_index_scan_desc( - orders_table_pkey_index_oid, orders_key_column_ids, orders_expr_types, - orders_key_values, runtime_keys); - - // Create the index scan plan node - planner::IndexScanPlan orders_index_scan_node( - orders_table, nullptr, orders_column_ids, orders_index_scan_desc); - - // Create the executors - executor::IndexScanExecutor orders_index_scan_executor( - &orders_index_scan_node, context.get()); - - auto orders_ids = ExecuteRead(&orders_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - assert(orders_ids.size() == 1); - assert(orders_ids[0].size() == 1); - - // Result: O_C_ID - auto c_id = orders_ids[0][0]; - - LOG_TRACE( - "sumOLAmount: SELECT SUM(OL_AMOUNT) FROM ORDER_LINE WHERE OL_O_ID = ? " - "AND OL_D_ID = ? AND OL_W_ID = ?"); - - // Construct index scan executor - std::vector order_line_column_ids = {COL_IDX_OL_AMOUNT}; - std::vector order_line_key_column_ids = { - COL_IDX_OL_O_ID, COL_IDX_OL_D_ID, COL_IDX_OL_W_ID}; - - std::vector order_line_expr_types; - - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector order_line_key_values; - - order_line_key_values.push_back(no_o_id); - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc order_line_index_scan_desc( - order_line_table_pkey_index_oid, order_line_key_column_ids, - order_line_expr_types, order_line_key_values, runtime_keys); - - planner::IndexScanPlan order_line_index_scan_node( - order_line_table, nullptr, order_line_column_ids, - order_line_index_scan_desc); - - executor::IndexScanExecutor order_line_index_scan_executor( - &order_line_index_scan_node, context.get()); - - auto order_line_index_scan_res = - ExecuteRead(&order_line_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - double sum_res = 0.0; - - // Workaround: Externanl sum - for (auto v : order_line_index_scan_res) { - assert(v.size() == 1); - sum_res += type::ValuePeeker::PeekDouble(v[0]); - } - - auto ol_total = type::ValueFactory::GetDecimalValue(sum_res); - - LOG_TRACE( - "deleteNewOrder: DELETE FROM NEW_ORDER WHERE NO_D_ID = ? AND NO_W_ID = " - "? AND NO_O_ID = ?"); - - // Construct index scan executor - std::vector new_order_delete_column_ids = {0}; - - std::vector new_order_delete_expr_types; - - new_order_delete_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - new_order_delete_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - new_order_delete_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector new_order_delete_key_values; - - new_order_delete_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - new_order_delete_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - new_order_delete_key_values.push_back(no_o_id); - - planner::IndexScanPlan::IndexScanDesc new_order_delete_idex_scan_desc( - new_order_table_pkey_index_oid, new_order_key_column_ids, - new_order_delete_expr_types, new_order_delete_key_values, runtime_keys); - - // Create index scan plan node - planner::IndexScanPlan new_order_delete_idex_scan_node( - new_order_table, nullptr, new_order_delete_column_ids, - new_order_delete_idex_scan_desc); - - // Create executors - executor::IndexScanExecutor new_order_delete_index_scan_executor( - &new_order_delete_idex_scan_node, context.get()); - - // Construct delete executor - planner::DeletePlan new_order_delete_node(new_order_table); - - executor::DeleteExecutor new_order_delete_executor(&new_order_delete_node, - context.get()); - - new_order_delete_executor.AddChild(&new_order_delete_index_scan_executor); - - // Execute the query - ExecuteDelete(&new_order_delete_executor); - - // Check if aborted - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - LOG_TRACE( - "updateOrders: UPDATE ORDERS SET O_CARRIER_ID = ? WHERE O_ID = ? AND " - "O_D_ID = ? AND O_W_ID = ?"); - - // Construct index scan executor - std::vector orders_update_column_ids = {COL_IDX_O_CARRIER_ID}; - - std::vector orders_update_key_values; - - orders_update_key_values.push_back(no_o_id); - orders_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - orders_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc orders_update_index_scan_desc( - orders_table_pkey_index_oid, orders_key_column_ids, orders_expr_types, - orders_update_key_values, runtime_keys); - - // Reuse the index scan desc created above since nothing different - planner::IndexScanPlan orders_update_index_scan_node( - orders_table, nullptr, orders_update_column_ids, - orders_update_index_scan_desc); - - executor::IndexScanExecutor orders_update_index_scan_executor( - &orders_update_index_scan_node, context.get()); - - // Construct update executor - TargetList orders_target_list; - DirectMapList orders_direct_map_list; - - size_t orders_column_count = 8; - for (oid_t col_itr = 0; col_itr < orders_column_count; col_itr++) { - // Skip O_CARRIER_ID - if (col_itr != COL_IDX_O_CARRIER_ID) { - orders_direct_map_list.emplace_back(col_itr, - std::make_pair(0, col_itr)); - } - } - type::Value orders_update_val = - type::ValueFactory::GetIntegerValue(o_carrier_id).Copy(); - - planner::DerivedAttribute carrier_id{ - expression::ExpressionUtil::ConstantValueFactory(orders_update_val)}; - orders_target_list.emplace_back(COL_IDX_O_CARRIER_ID, carrier_id); - - std::unique_ptr orders_project_info( - new planner::ProjectInfo(std::move(orders_target_list), - std::move(orders_direct_map_list))); - planner::UpdatePlan orders_update_node(orders_table, - std::move(orders_project_info)); - - executor::UpdateExecutor orders_update_executor(&orders_update_node, - context.get()); - - orders_update_executor.AddChild(&orders_update_index_scan_executor); - - // Execute the query - ExecuteUpdate(&orders_update_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - LOG_TRACE( - "updateOrderLine: UPDATE ORDER_LINE SET OL_DELIVERY_D = ? WHERE " - "OL_O_ID = ? AND OL_D_ID = ? AND OL_W_ID = ?"); - - // Construct index scan executor - std::vector order_line_update_column_ids = {COL_IDX_OL_DELIVERY_D}; - - std::vector order_line_update_key_values; - - order_line_update_key_values.push_back(no_o_id); - order_line_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - order_line_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc order_line_update_index_scan_desc( - order_line_table_pkey_index_oid, order_line_key_column_ids, - order_line_expr_types, order_line_update_key_values, runtime_keys); - - planner::IndexScanPlan order_line_update_index_scan_node( - order_line_table, nullptr, order_line_update_column_ids, - order_line_update_index_scan_desc); - - executor::IndexScanExecutor order_line_update_index_scan_executor( - &order_line_update_index_scan_node, context.get()); - - // Construct update executor - TargetList order_line_target_list; - DirectMapList order_line_direct_map_list; - - size_t order_line_column_count = 10; - for (oid_t col_itr = 0; col_itr < order_line_column_count; col_itr++) { - // Skip OL_DELIVERY_D - if (col_itr != COL_IDX_OL_DELIVERY_D) { - order_line_direct_map_list.emplace_back(col_itr, - std::make_pair(0, col_itr)); - } - } - type::Value order_line_update_val = - type::ValueFactory::GetTimestampValue(0).Copy(); - - planner::DerivedAttribute delivery_id{ - expression::ExpressionUtil::ConstantValueFactory( - order_line_update_val)}; - order_line_target_list.emplace_back(COL_IDX_OL_DELIVERY_D, delivery_id); - - std::unique_ptr order_line_project_info( - new planner::ProjectInfo(std::move(order_line_target_list), - std::move(order_line_direct_map_list))); - planner::UpdatePlan order_line_update_node( - order_line_table, std::move(order_line_project_info)); - - executor::UpdateExecutor order_line_update_executor(&order_line_update_node, - context.get()); - - order_line_update_executor.AddChild(&order_line_update_index_scan_executor); - - ExecuteUpdate(&order_line_update_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - LOG_TRACE( - "updateCustomer: UPDATE CUSTOMER SET C_BALANCE = C_BALANCE + ? WHERE " - "C_ID = ? AND C_D_ID = ? AND C_W_ID = ?"); - - // Construct index scan executor - std::vector customer_column_ids = {COL_IDX_C_BALANCE}; - std::vector customer_key_column_ids = {COL_IDX_C_ID, COL_IDX_C_D_ID, - COL_IDX_C_W_ID}; - - std::vector customer_expr_types; - - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector customer_key_values; - - customer_key_values.push_back(c_id); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_index_scan_desc( - customer_table_pkey_index_oid, customer_key_column_ids, - customer_expr_types, customer_key_values, runtime_keys); - - planner::IndexScanPlan customer_index_scan_node( - customer_table, nullptr, customer_column_ids, customer_index_scan_desc); - - executor::IndexScanExecutor customer_index_scan_executor( - &customer_index_scan_node, context.get()); - - // Construct update executor - TargetList customer_target_list; - DirectMapList customer_direct_map_list; - - size_t customer_column_count = 21; - for (oid_t col_itr = 0; col_itr < customer_column_count; col_itr++) { - // Skip OL_DELIVERY_D - if (col_itr != COL_IDX_C_BALANCE) { - customer_direct_map_list.emplace_back(col_itr, - std::make_pair(0, col_itr)); - } - } - - // Expressions - // Tuple value expression - auto tuple_val_expr = expression::ExpressionUtil::TupleValueFactory( - type::TypeId::INTEGER, 0, COL_IDX_C_BALANCE); - // Constant value expression - auto constant_val_expr = - expression::ExpressionUtil::ConstantValueFactory(ol_total); - // + operator expression - auto plus_operator_expr = expression::ExpressionUtil::OperatorFactory( - ExpressionType::OPERATOR_PLUS, type::TypeId::INTEGER, tuple_val_expr, - constant_val_expr); - - planner::DerivedAttribute c_balance{plus_operator_expr}; - customer_target_list.emplace_back(COL_IDX_C_BALANCE, c_balance); - - std::unique_ptr customer_project_info( - new planner::ProjectInfo(std::move(customer_target_list), - std::move(customer_direct_map_list))); - planner::UpdatePlan customer_update_node(customer_table, - std::move(customer_project_info)); - - executor::UpdateExecutor customer_update_executor(&customer_update_node, - context.get()); - - customer_update_executor.AddChild(&customer_index_scan_executor); - - // Execute the query - ExecuteUpdate(&customer_update_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - } - - assert(txn->GetResult() == ResultType::SUCCESS); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - LOG_TRACE("commit successfully"); - return true; - } else { - assert(result == ResultType::ABORTED || result == ResultType::FAILURE); - return false; - } -} -} -} -} diff --git a/src/main/tpcc/tpcc_loader.cpp b/src/main/tpcc/tpcc_loader.cpp deleted file mode 100644 index 44d8e07e4b7..00000000000 --- a/src/main/tpcc/tpcc_loader.cpp +++ /dev/null @@ -1,1764 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_loader.cpp -// -// Identification: src/main/tpcc/tpcc_loader.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_configuration.h" -#include "catalog/catalog.h" -#include "catalog/schema.h" -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" -#include "executor/abstract_executor.h" -#include "executor/insert_executor.h" -#include "executor/executor_context.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "index/index_factory.h" -#include "planner/insert_plan.h" -#include "storage/tile.h" -#include "storage/tile_group.h" -#include "storage/data_table.h" -#include "storage/table_factory.h" -#include "storage/database.h" -#include "common/internal_types.h" - - -// Logging mode -// extern peloton::LoggingType peloton_logging_mode; - -// disable unused const variable warning for clang -#ifdef __APPLE__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-const-variable" -#endif - -namespace peloton { -namespace benchmark { -namespace tpcc { - -///////////////////////////////////////////////////////// -// Constants -///////////////////////////////////////////////////////// - -const size_t name_length = 32; -const size_t middle_name_length = 2; -const size_t data_length = 64; -const size_t state_length = 16; -const size_t zip_length = 9; -const size_t street_length = 32; -const size_t city_length = 32; -const size_t credit_length = 2; -const size_t phone_length = 32; -const size_t dist_length = 32; - -double item_min_price = 1.0; -double item_max_price = 100.0; - -double warehouse_name_length = 16; -double warehouse_min_tax = 0.0; -double warehouse_max_tax = 0.2; -double warehouse_initial_ytd = 300000.00f; - -double district_name_length = 16; -double district_min_tax = 0.0; -double district_max_tax = 0.2; -double district_initial_ytd = 30000.00f; - -std::string customers_good_credit = "GC"; -std::string customers_bad_credit = "BC"; -double customers_bad_credit_ratio = 0.1; -double customers_init_credit_lim = 50000.0; -double customers_min_discount = 0; -double customers_max_discount = 0.5; -double customers_init_balance = -10.0; -double customers_init_ytd = 10.0; -int customers_init_payment_cnt = 1; -int customers_init_delivery_cnt = 0; - -double history_init_amount = 10.0; -size_t history_data_length = 32; - -int orders_min_ol_cnt = 5; -int orders_max_ol_cnt = 15; -int orders_init_all_local = 1; -int orders_null_carrier_id = 0; -int orders_min_carrier_id = 1; -int orders_max_carrier_id = 10; - -int new_orders_per_district = 900; // 900 - -int order_line_init_quantity = 5; -int order_line_max_ol_quantity = 10; -double order_line_min_amount = 0.01; -size_t order_line_dist_info_length = 32; - -double stock_original_ratio = 0.1; -int stock_min_quantity = 10; -int stock_max_quantity = 100; -int stock_dist_count = 10; - -double payment_min_amount = 1.0; -double payment_max_amount = 5000.0; - -int stock_min_threshold = 10; -int stock_max_threshold = 20; - -double new_order_remote_txns = 0.01; - -const int syllable_count = 10; -const char *syllables[syllable_count] = {"BAR", "OUGHT", "ABLE", "PRI", - "PRES", "ESES", "ANTI", "CALLY", - "ATION", "EING"}; - -const std::string data_constant = std::string("FOO"); - -NURandConstant nu_rand_const; - -///////////////////////////////////////////////////////// -// Create the tables -///////////////////////////////////////////////////////// - -storage::Database *tpcc_database; -storage::DataTable *warehouse_table; -storage::DataTable *district_table; -storage::DataTable *item_table; -storage::DataTable *customer_table; -storage::DataTable *history_table; -storage::DataTable *stock_table; -storage::DataTable *orders_table; -storage::DataTable *new_order_table; -storage::DataTable *order_line_table; - -const bool own_schema = true; -const bool adapt_table = false; -const bool is_inlined = false; -const bool unique_index = false; -const bool allocate = true; - -void CreateWarehouseTable() { - /* - CREATE TABLE WAREHOUSE ( - W_ID SMALLINT DEFAULT '0' NOT NULL, - W_NAME VARCHAR(16) DEFAULT NULL, - W_STREET_1 VARCHAR(32) DEFAULT NULL, - W_STREET_2 VARCHAR(32) DEFAULT NULL, - W_CITY VARCHAR(32) DEFAULT NULL, - W_STATE VARCHAR(2) DEFAULT NULL, - W_ZIP VARCHAR(9) DEFAULT NULL, - W_TAX FLOAT DEFAULT NULL, - W_YTD FLOAT DEFAULT NULL, - CONSTRAINT W_PK_ARRAY PRIMARY KEY (W_ID) - ); - */ - - // Create schema first - std::vector warehouse_columns; - - auto w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "W_ID", is_inlined); - warehouse_columns.push_back(w_id_column); - auto w_name_column = catalog::Column( - type::TypeId::VARCHAR, warehouse_name_length, "W_NAME", is_inlined); - warehouse_columns.push_back(w_name_column); - auto w_street_1_column = catalog::Column(type::TypeId::VARCHAR, street_length, - "W_STREET_1", is_inlined); - warehouse_columns.push_back(w_street_1_column); - auto w_street_2_column = catalog::Column(type::TypeId::VARCHAR, street_length, - "W_STREET_2", is_inlined); - warehouse_columns.push_back(w_street_2_column); - auto w_city_column = - catalog::Column(type::TypeId::VARCHAR, city_length, "W_CITY", is_inlined); - warehouse_columns.push_back(w_city_column); - auto w_state_column = - catalog::Column(type::TypeId::VARCHAR, state_length, "W_STATE", is_inlined); - warehouse_columns.push_back(w_state_column); - auto w_zip_column = - catalog::Column(type::TypeId::VARCHAR, zip_length, "W_ZIP", is_inlined); - warehouse_columns.push_back(w_zip_column); - auto w_tax_column = catalog::Column( - type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), "W_TAX", is_inlined); - warehouse_columns.push_back(w_tax_column); - auto w_ytd_column = catalog::Column( - type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), "W_YTD", is_inlined); - warehouse_columns.push_back(w_ytd_column); - - catalog::Schema *table_schema = new catalog::Schema(warehouse_columns); - std::string table_name("WAREHOUSE"); - - warehouse_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, warehouse_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(warehouse_table); - - // Primary index on W_ID - std::vector key_attrs = {0}; - - auto tuple_schema = warehouse_table->GetSchema(); - catalog::Schema *key_schema = - catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - bool unique = true; - - index::IndexMetadata *index_metadata = new index::IndexMetadata( - "warehouse_pkey", warehouse_table_pkey_index_oid, warehouse_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, unique); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - - warehouse_table->AddIndex(pkey_index); -} - -void CreateDistrictTable() { - /* - CREATE TABLE DISTRICT ( - D_ID TINYINT DEFAULT '0' NOT NULL, - D_W_ID SMALLINT DEFAULT '0' NOT NULL REFERENCES WAREHOUSE (W_ID), - D_NAME VARCHAR(16) DEFAULT NULL, - D_STREET_1 VARCHAR(32) DEFAULT NULL, - D_STREET_2 VARCHAR(32) DEFAULT NULL, - D_CITY VARCHAR(32) DEFAULT NULL, - D_STATE VARCHAR(2) DEFAULT NULL, - D_ZIP VARCHAR(9) DEFAULT NULL, - D_TAX FLOAT DEFAULT NULL, - D_YTD FLOAT DEFAULT NULL, - D_NEXT_O_ID INT DEFAULT NULL, - PRIMARY KEY (D_W_ID,D_ID) - ); - */ - - // Create schema first - std::vector district_columns; - - auto d_id_column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "D_ID", is_inlined); - district_columns.push_back(d_id_column); - auto d_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "D_W_ID", is_inlined); - district_columns.push_back(d_w_id_column); - auto d_name_column = catalog::Column(type::TypeId::VARCHAR, district_name_length, - "D_NAME", is_inlined); - district_columns.push_back(d_name_column); - auto d_street_1_column = catalog::Column(type::TypeId::VARCHAR, street_length, - "D_STREET_1", is_inlined); - district_columns.push_back(d_street_1_column); - auto d_street_2_column = catalog::Column(type::TypeId::VARCHAR, street_length, - "D_STREET_2", is_inlined); - district_columns.push_back(d_street_2_column); - auto d_city_column = - catalog::Column(type::TypeId::VARCHAR, city_length, "D_CITY", is_inlined); - district_columns.push_back(d_city_column); - auto d_state_column = - catalog::Column(type::TypeId::VARCHAR, state_length, "D_STATE", is_inlined); - district_columns.push_back(d_state_column); - auto d_zip_column = - catalog::Column(type::TypeId::VARCHAR, zip_length, "D_ZIP", is_inlined); - district_columns.push_back(d_zip_column); - auto d_tax_column = catalog::Column( - type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), "D_TAX", is_inlined); - district_columns.push_back(d_tax_column); - auto d_ytd_column = catalog::Column( - type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), "D_YTD", is_inlined); - district_columns.push_back(d_ytd_column); - auto d_next_o_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "D_NEXT_O_ID", is_inlined); - district_columns.push_back(d_next_o_id_column); - - catalog::Schema *table_schema = new catalog::Schema(district_columns); - std::string table_name("DISTRICT"); - - district_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, district_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(district_table); - - // Primary index on D_ID, D_W_ID - std::vector key_attrs = {0, 1}; - - auto tuple_schema = district_table->GetSchema(); - catalog::Schema *key_schema = - catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - bool unique = true; - - index::IndexMetadata *index_metadata = new index::IndexMetadata( - "district_pkey", district_table_pkey_index_oid, - district_table_pkey_index_oid, district_table_oid, state.index, - IndexConstraintType::PRIMARY_KEY, tuple_schema, key_schema, key_attrs, - unique); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - - district_table->AddIndex(pkey_index); -} - -void CreateItemTable() { - /* - CREATE TABLE ITEM ( - I_ID INTEGER DEFAULT '0' NOT NULL, - I_IM_ID INTEGER DEFAULT NULL, - I_NAME VARCHAR(32) DEFAULT NULL, - I_PRICE FLOAT DEFAULT NULL, - I_DATA VARCHAR(64) DEFAULT NULL, - CONSTRAINT I_PK_ARRAY PRIMARY KEY (I_ID) - ); - */ - - // Create schema first - std::vector item_columns; - - auto i_id_column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "I_ID", is_inlined); - item_columns.push_back(i_id_column); - auto i_im_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "I_IM_ID", is_inlined); - item_columns.push_back(i_im_id_column); - auto i_name_column = - catalog::Column(type::TypeId::VARCHAR, name_length, "I_NAME", is_inlined); - item_columns.push_back(i_name_column); - auto i_price_column = catalog::Column( - type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), "I_PRICE", is_inlined); - item_columns.push_back(i_price_column); - auto i_data_column = - catalog::Column(type::TypeId::VARCHAR, data_length, "I_DATA", is_inlined); - item_columns.push_back(i_data_column); - - catalog::Schema *table_schema = new catalog::Schema(item_columns); - std::string table_name("ITEM"); - - item_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, item_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(item_table); - - // Primary index on I_ID - std::vector key_attrs = {0}; - - auto tuple_schema = item_table->GetSchema(); - catalog::Schema *key_schema = - catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - bool unique = true; - - index::IndexMetadata *index_metadata = new index::IndexMetadata( - "item_pkey", item_table_pkey_index_oid, item_table_oid, tpcc_database_oid, - state.index, IndexConstraintType::PRIMARY_KEY, tuple_schema, - key_schema, key_attrs, unique); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - item_table->AddIndex(pkey_index); -} - -void CreateCustomerTable() { - /* - CREATE TABLE CUSTOMER ( - C_ID INTEGER DEFAULT '0' NOT NULL, - C_D_ID TINYINT DEFAULT '0' NOT NULL, - C_W_ID SMALLINT DEFAULT '0' NOT NULL, - C_FIRST VARCHAR(32) DEFAULT NULL, - C_MIDDLE VARCHAR(2) DEFAULT NULL, - C_LAST VARCHAR(32) DEFAULT NULL, - C_STREET_1 VARCHAR(32) DEFAULT NULL, - C_STREET_2 VARCHAR(32) DEFAULT NULL, - C_CITY VARCHAR(32) DEFAULT NULL, - C_STATE VARCHAR(2) DEFAULT NULL, - C_ZIP VARCHAR(9) DEFAULT NULL, - C_PHONE VARCHAR(32) DEFAULT NULL, - C_SINCE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - C_CREDIT VARCHAR(2) DEFAULT NULL, - C_CREDIT_LIM FLOAT DEFAULT NULL, - C_DISCOUNT FLOAT DEFAULT NULL, - C_BALANCE FLOAT DEFAULT NULL, - C_YTD_PAYMENT FLOAT DEFAULT NULL, - C_PAYMENT_CNT INTEGER DEFAULT NULL, - C_DELIVERY_CNT INTEGER DEFAULT NULL, - C_DATA VARCHAR(500), - PRIMARY KEY (C_W_ID,C_D_ID,C_ID), - UNIQUE (C_W_ID,C_D_ID,C_LAST,C_FIRST), - CONSTRAINT C_FKEY_D FOREIGN KEY (C_D_ID, C_W_ID) REFERENCES DISTRICT (D_ID, - D_W_ID) - ); - CREATE INDEX IDX_CUSTOMER ON CUSTOMER (C_W_ID,C_D_ID,C_LAST); - */ - - // Create schema first - std::vector customer_columns; - - auto c_id_column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "C_ID", is_inlined); - customer_columns.push_back(c_id_column); - auto c_d_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "C_D_ID", is_inlined); - customer_columns.push_back(c_d_id_column); - auto c_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "C_W_ID", is_inlined); - customer_columns.push_back(c_w_id_column); - auto c_first_name_column = - catalog::Column(type::TypeId::VARCHAR, name_length, "C_FIRST", is_inlined); - customer_columns.push_back(c_first_name_column); - auto c_middle_name_column = catalog::Column( - type::TypeId::VARCHAR, middle_name_length, "C_MIDDLE", is_inlined); - customer_columns.push_back(c_middle_name_column); - auto c_last_name_column = - catalog::Column(type::TypeId::VARCHAR, name_length, "C_LAST", is_inlined); - customer_columns.push_back(c_last_name_column); - auto c_street_1_column = catalog::Column(type::TypeId::VARCHAR, street_length, - "C_STREET_1", is_inlined); - customer_columns.push_back(c_street_1_column); - auto c_street_2_column = catalog::Column(type::TypeId::VARCHAR, street_length, - "C_STREET_2", is_inlined); - customer_columns.push_back(c_street_2_column); - auto c_city_column = - catalog::Column(type::TypeId::VARCHAR, city_length, "C_CITY", is_inlined); - customer_columns.push_back(c_city_column); - auto c_state_column = - catalog::Column(type::TypeId::VARCHAR, state_length, "C_STATE", is_inlined); - customer_columns.push_back(c_state_column); - auto c_zip_column = - catalog::Column(type::TypeId::VARCHAR, zip_length, "C_ZIP", is_inlined); - customer_columns.push_back(c_zip_column); - auto c_phone_column = - catalog::Column(type::TypeId::VARCHAR, phone_length, "C_PHONE", is_inlined); - customer_columns.push_back(c_phone_column); - auto c_since_column = - catalog::Column(type::TypeId::TIMESTAMP, type::Type::GetTypeSize(type::TypeId::TIMESTAMP), - "C_SINCE", is_inlined); - customer_columns.push_back(c_since_column); - auto c_credit_column = catalog::Column(type::TypeId::VARCHAR, credit_length, - "C_CREDIT", is_inlined); - customer_columns.push_back(c_credit_column); - auto c_credit_lim_column = - catalog::Column(type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), - "C_CREDIT_LIM", is_inlined); - customer_columns.push_back(c_credit_lim_column); - auto c_discount_column = - catalog::Column(type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), - "C_DISCOUNT", is_inlined); - customer_columns.push_back(c_discount_column); - auto c_balance_column = - catalog::Column(type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), - "C_BALANCE", is_inlined); - customer_columns.push_back(c_balance_column); - auto c_ytd_payment_column = - catalog::Column(type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), - "C_YTD_PAYMENT", is_inlined); - customer_columns.push_back(c_ytd_payment_column); - auto c_payment_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "C_PAYMENT_CNT", is_inlined); - customer_columns.push_back(c_payment_column); - auto c_delivery_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "C_DELIVERY_CNT", is_inlined); - customer_columns.push_back(c_delivery_column); - auto c_data_column = - catalog::Column(type::TypeId::VARCHAR, data_length, "C_DATA", is_inlined); - customer_columns.push_back(c_data_column); - - catalog::Schema *table_schema = new catalog::Schema(customer_columns); - std::string table_name("CUSTOMER"); - - customer_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, customer_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(customer_table); - - auto tuple_schema = customer_table->GetSchema(); - std::vector key_attrs; - catalog::Schema *key_schema = nullptr; - index::IndexMetadata *index_metadata = nullptr; - - // Primary index on C_ID, C_D_ID, C_W_ID - key_attrs = {0, 1, 2}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - index_metadata = new index::IndexMetadata( - "customer_pkey", customer_table_pkey_index_oid, customer_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, true); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - customer_table->AddIndex(pkey_index); - - // Secondary index on C_W_ID, C_D_ID, C_LAST - key_attrs = {1, 2, 5}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - index_metadata = new index::IndexMetadata( - "customer_skey", customer_table_skey_index_oid, customer_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::INVALID, - tuple_schema, key_schema, key_attrs, false); - - std::shared_ptr skey_index( - index::IndexFactory::GetIndex(index_metadata)); - customer_table->AddIndex(skey_index); -} - -void CreateHistoryTable() { - /* - CREATE TABLE HISTORY ( - H_C_ID INTEGER DEFAULT NULL, - H_C_D_ID TINYINT DEFAULT NULL, - H_C_W_ID SMALLINT DEFAULT NULL, - H_D_ID TINYINT DEFAULT NULL, - H_W_ID SMALLINT DEFAULT '0' NOT NULL, - H_DATE TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - H_AMOUNT FLOAT DEFAULT NULL, - H_DATA VARCHAR(32) DEFAULT NULL, - CONSTRAINT H_FKEY_C FOREIGN KEY (H_C_ID, H_C_D_ID, H_C_W_ID) REFERENCES - CUSTOMER (C_ID, C_D_ID, C_W_ID), - CONSTRAINT H_FKEY_D FOREIGN KEY (H_D_ID, H_W_ID) REFERENCES DISTRICT (D_ID, - D_W_ID) - ); - */ - - // Create schema first - std::vector history_columns; - - auto h_c_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "H_C_ID", is_inlined); - history_columns.push_back(h_c_id_column); - auto h_c_d_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "H_C_D_ID", is_inlined); - history_columns.push_back(h_c_d_id_column); - auto h_c_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "H_C_W_ID", is_inlined); - history_columns.push_back(h_c_w_id_column); - auto h_d_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "H_D_ID", is_inlined); - history_columns.push_back(h_d_id_column); - auto h_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "H_W_ID", is_inlined); - history_columns.push_back(h_w_id_column); - auto h_date_column = - catalog::Column(type::TypeId::TIMESTAMP, type::Type::GetTypeSize(type::TypeId::TIMESTAMP), - "H_DATE", is_inlined); - history_columns.push_back(h_date_column); - auto h_amount_column = - catalog::Column(type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), - "H_AMOUNT", is_inlined); - history_columns.push_back(h_amount_column); - auto h_data_column = catalog::Column(type::TypeId::VARCHAR, history_data_length, - "H_DATA", is_inlined); - history_columns.push_back(h_data_column); - - catalog::Schema *table_schema = new catalog::Schema(history_columns); - std::string table_name("HISTORY"); - - history_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, history_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(history_table); -} - -void CreateStockTable() { - /* - CREATE TABLE STOCK ( - S_I_ID INTEGER DEFAULT '0' NOT NULL REFERENCES ITEM (I_ID), - S_W_ID SMALLINT DEFAULT '0 ' NOT NULL REFERENCES WAREHOUSE (W_ID), - S_QUANTITY INTEGER DEFAULT '0' NOT NULL, - S_DIST_01 VARCHAR(32) DEFAULT NULL, - S_DIST_02 VARCHAR(32) DEFAULT NULL, - S_DIST_03 VARCHAR(32) DEFAULT NULL, - S_DIST_04 VARCHAR(32) DEFAULT NULL, - S_DIST_05 VARCHAR(32) DEFAULT NULL, - S_DIST_06 VARCHAR(32) DEFAULT NULL, - S_DIST_07 VARCHAR(32) DEFAULT NULL, - S_DIST_08 VARCHAR(32) DEFAULT NULL, - S_DIST_09 VARCHAR(32) DEFAULT NULL, - S_DIST_10 VARCHAR(32) DEFAULT NULL, - S_YTD INTEGER DEFAULT NULL, - S_ORDER_CNT INTEGER DEFAULT NULL, - S_REMOTE_CNT INTEGER DEFAULT NULL, - S_DATA VARCHAR(64) DEFAULT NULL, - PRIMARY KEY (S_W_ID,S_I_ID) - ); - */ - - // Create schema first - std::vector stock_columns; - - auto s_i_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "S_I_ID", is_inlined); - stock_columns.push_back(s_i_id_column); - auto s_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "S_W_ID", is_inlined); - stock_columns.push_back(s_w_id_column); - auto s_quantity_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "S_QUANTITY", is_inlined); - stock_columns.push_back(s_quantity_column); - auto s_dist_01_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_01", is_inlined); - stock_columns.push_back(s_dist_01_column); - auto s_dist_02_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_02", is_inlined); - stock_columns.push_back(s_dist_02_column); - auto s_dist_03_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_03", is_inlined); - stock_columns.push_back(s_dist_03_column); - auto s_dist_04_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_04", is_inlined); - stock_columns.push_back(s_dist_04_column); - auto s_dist_05_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_05", is_inlined); - stock_columns.push_back(s_dist_05_column); - auto s_dist_06_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_06", is_inlined); - stock_columns.push_back(s_dist_06_column); - auto s_dist_07_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_07", is_inlined); - stock_columns.push_back(s_dist_07_column); - auto s_dist_08_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_08", is_inlined); - stock_columns.push_back(s_dist_08_column); - auto s_dist_09_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_09", is_inlined); - stock_columns.push_back(s_dist_09_column); - auto s_dist_10_column = - catalog::Column(type::TypeId::VARCHAR, dist_length, "S_DIST_10", is_inlined); - stock_columns.push_back(s_dist_10_column); - auto s_ytd_column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "S_YTD", is_inlined); - stock_columns.push_back(s_ytd_column); - auto s_order_cnt_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "S_ORDER_CNT", is_inlined); - stock_columns.push_back(s_order_cnt_column); - auto s_discount_cnt_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "S_REMOTE_CNT", is_inlined); - stock_columns.push_back(s_discount_cnt_column); - auto s_data_column = - catalog::Column(type::TypeId::VARCHAR, data_length, "S_DATA", is_inlined); - stock_columns.push_back(s_data_column); - - catalog::Schema *table_schema = new catalog::Schema(stock_columns); - std::string table_name("STOCK"); - - stock_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, stock_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(stock_table); - - // Primary index on S_I_ID, S_W_ID - std::vector key_attrs = {0, 1}; - - auto tuple_schema = stock_table->GetSchema(); - catalog::Schema *key_schema = - catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - bool unique = true; - - index::IndexMetadata *index_metadata = new index::IndexMetadata( - "stock_pkey", stock_table_pkey_index_oid, stock_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, unique); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - stock_table->AddIndex(pkey_index); -} - -void CreateOrdersTable() { - /* - CREATE TABLE ORDERS ( - O_ID INTEGER DEFAULT '0' NOT NULL, - O_C_ID INTEGER DEFAULT NULL, - O_D_ID TINYINT DEFAULT '0' NOT NULL, - O_W_ID SMALLINT DEFAULT '0' NOT NULL, - O_ENTRY_D TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, - O_CARRIER_ID INTEGER DEFAULT NULL, - O_OL_CNT INTEGER DEFAULT NULL, - O_ALL_LOCAL INTEGER DEFAULT NULL, - PRIMARY KEY (O_W_ID,O_D_ID,O_ID), - UNIQUE (O_W_ID,O_D_ID,O_C_ID,O_ID), - CONSTRAINT O_FKEY_C FOREIGN KEY (O_C_ID, O_D_ID, O_W_ID) REFERENCES CUSTOMER - (C_ID, C_D_ID, C_W_ID) - ); - CREATE INDEX IDX_ORDERS ON ORDERS (O_W_ID,O_D_ID,O_C_ID); - */ - - // Create schema first - std::vector orders_columns; - - auto o_id_column = catalog::Column( - type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "O_ID", is_inlined); - orders_columns.push_back(o_id_column); - auto o_c_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "O_C_ID", is_inlined); - orders_columns.push_back(o_c_id_column); - auto o_d_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "O_D_ID", is_inlined); - orders_columns.push_back(o_d_id_column); - auto o_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "O_W_ID", is_inlined); - orders_columns.push_back(o_w_id_column); - auto o_entry_d_column = - catalog::Column(type::TypeId::TIMESTAMP, type::Type::GetTypeSize(type::TypeId::TIMESTAMP), - "O_ENTRY_D", is_inlined); - orders_columns.push_back(o_entry_d_column); - auto o_carrier_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "O_CARRIER_ID", is_inlined); - orders_columns.push_back(o_carrier_id_column); - auto o_ol_cnt_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "O_OL_CNT", is_inlined); - orders_columns.push_back(o_ol_cnt_column); - auto o_all_local_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "O_ALL_LOCAL", is_inlined); - orders_columns.push_back(o_all_local_column); - - catalog::Schema *table_schema = new catalog::Schema(orders_columns); - std::string table_name("ORDERS"); - - orders_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, orders_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(orders_table); - - auto tuple_schema = customer_table->GetSchema(); - std::vector key_attrs; - catalog::Schema *key_schema = nullptr; - index::IndexMetadata *index_metadata = nullptr; - - // Primary index on O_ID, O_D_ID, O_W_ID - key_attrs = {0, 2, 3}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - index_metadata = new index::IndexMetadata( - "orders_pkey", orders_table_pkey_index_oid, orders_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, true); - - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - orders_table->AddIndex(pkey_index); - - // Secondary index on O_C_ID, O_D_ID, O_W_ID - key_attrs = {1, 2, 3}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - index_metadata = new index::IndexMetadata( - "orders_skey", orders_table_skey_index_oid, orders_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::INVALID, - tuple_schema, key_schema, key_attrs, false); - - std::shared_ptr skey_index( - index::IndexFactory::GetIndex(index_metadata)); - orders_table->AddIndex(skey_index); -} - -void CreateNewOrderTable() { - /* - CREATE TABLE NEW_ORDER ( - NO_O_ID INTEGER DEFAULT '0' NOT NULL, - NO_D_ID TINYINT DEFAULT '0' NOT NULL, - NO_W_ID SMALLINT DEFAULT '0' NOT NULL, - CONSTRAINT NO_PK_TREE PRIMARY KEY (NO_D_ID,NO_W_ID,NO_O_ID), - CONSTRAINT NO_FKEY_O FOREIGN KEY (NO_O_ID, NO_D_ID, NO_W_ID) REFERENCES - ORDERS (O_ID, O_D_ID, O_W_ID) - ); - */ - - // Create schema first - std::vector new_order_columns; - - auto no_o_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "NO_O_ID", is_inlined); - new_order_columns.push_back(no_o_id_column); - auto no_d_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "NO_D_ID", is_inlined); - new_order_columns.push_back(no_d_id_column); - auto no_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "NO_W_ID", is_inlined); - new_order_columns.push_back(no_w_id_column); - - catalog::Schema *table_schema = new catalog::Schema(new_order_columns); - std::string table_name("NEW_ORDER"); - - new_order_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, new_order_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(new_order_table); - - // Primary index on NO_O_ID, NO_D_ID, NO_W_ID - std::vector key_attrs = {0, 1, 2}; - - auto tuple_schema = new_order_table->GetSchema(); - catalog::Schema *key_schema = - catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - bool unique = true; - - index::IndexMetadata *index_metadata = new index::IndexMetadata( - "new_order_pkey", new_order_table_pkey_index_oid, new_order_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, unique); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - new_order_table->AddIndex(pkey_index); -} - -void CreateOrderLineTable() { - /* - CREATE TABLE ORDER_LINE ( - OL_O_ID INTEGER DEFAULT '0' NOT NULL, - OL_D_ID TINYINT DEFAULT '0' NOT NULL, - OL_W_ID SMALLINT DEFAULT '0' NOT NULL, - OL_NUMBER INTEGER DEFAULT '0' NOT NULL, - OL_I_ID INTEGER DEFAULT NULL, - OL_SUPPLY_W_ID SMALLINT DEFAULT NULL, - OL_DELIVERY_D TIMESTAMP DEFAULT NULL, - OL_QUANTITY INTEGER DEFAULT NULL, - OL_AMOUNT FLOAT DEFAULT NULL, - OL_DIST_INFO VARCHAR(32) DEFAULT NULL, - PRIMARY KEY (OL_W_ID,OL_D_ID,OL_O_ID,OL_NUMBER), - CONSTRAINT OL_FKEY_O FOREIGN KEY (OL_O_ID, OL_D_ID, OL_W_ID) REFERENCES - ORDERS (O_ID, O_D_ID, O_W_ID), - CONSTRAINT OL_FKEY_S FOREIGN KEY (OL_I_ID, OL_SUPPLY_W_ID) REFERENCES STOCK - (S_I_ID, S_W_ID) - ); - CREATE INDEX IDX_ORDER_LINE_TREE ON ORDER_LINE (OL_W_ID,OL_D_ID,OL_O_ID); - */ - - // Create schema first - std::vector order_line_columns; - - auto ol_o_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_O_ID", is_inlined); - order_line_columns.push_back(ol_o_id_column); - auto ol_d_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_D_ID", is_inlined); - order_line_columns.push_back(ol_d_id_column); - auto ol_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_W_ID", is_inlined); - order_line_columns.push_back(ol_w_id_column); - auto ol_number_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_NUMBER", is_inlined); - order_line_columns.push_back(ol_number_column); - auto ol_i_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_I_ID", is_inlined); - order_line_columns.push_back(ol_i_id_column); - auto ol_supply_w_id_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_SUPPLY_W_ID", is_inlined); - order_line_columns.push_back(ol_supply_w_id_column); - auto ol_delivery_d_column = - catalog::Column(type::TypeId::TIMESTAMP, type::Type::GetTypeSize(type::TypeId::TIMESTAMP), - "OL_DELIVERY_D", is_inlined); - order_line_columns.push_back(ol_delivery_d_column); - auto ol_quantity_column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "OL_QUANTITY", is_inlined); - order_line_columns.push_back(ol_quantity_column); - auto ol_amount_column = - catalog::Column(type::TypeId::DECIMAL, type::Type::GetTypeSize(type::TypeId::DECIMAL), - "OL_AMOUNT", is_inlined); - order_line_columns.push_back(ol_amount_column); - auto ol_dist_info_column = - catalog::Column(type::TypeId::VARCHAR, order_line_dist_info_length, - "OL_DIST_INFO", is_inlined); - order_line_columns.push_back(ol_dist_info_column); - - catalog::Schema *table_schema = new catalog::Schema(order_line_columns); - std::string table_name("ORDER_LINE"); - - order_line_table = storage::TableFactory::GetDataTable( - tpcc_database_oid, order_line_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - tpcc_database->AddTable(order_line_table); - - auto tuple_schema = order_line_table->GetSchema(); - std::vector key_attrs; - catalog::Schema *key_schema = nullptr; - index::IndexMetadata *index_metadata = nullptr; - - // Primary index on OL_O_ID, OL_D_ID, OL_W_ID, OL_NUMBER - key_attrs = {0, 1, 2, 3}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - index_metadata = new index::IndexMetadata( - "order_line_pkey", order_line_table_pkey_index_oid, order_line_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, true); - - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - order_line_table->AddIndex(pkey_index); - - // Secondary index on OL_O_ID, OL_D_ID, OL_W_ID - key_attrs = {0, 1, 2}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - index_metadata = new index::IndexMetadata( - "order_line_skey", order_line_table_skey_index_oid, order_line_table_oid, - tpcc_database_oid, state.index, IndexConstraintType::INVALID, - tuple_schema, key_schema, key_attrs, false); - - std::shared_ptr skey_index( - index::IndexFactory::GetIndex(index_metadata)); - order_line_table->AddIndex(skey_index); -} - -void CreateTPCCDatabase() { - // Clean up - delete tpcc_database; - tpcc_database = nullptr; - warehouse_table = nullptr; - district_table = nullptr; - item_table = nullptr; - customer_table = nullptr; - history_table = nullptr; - stock_table = nullptr; - orders_table = nullptr; - new_order_table = nullptr; - order_line_table = nullptr; - - auto catalog = catalog::Catalog::GetInstance(); - tpcc_database = new storage::Database(tpcc_database_oid); - catalog->AddDatabase(tpcc_database); - - CreateWarehouseTable(); - CreateDistrictTable(); - CreateItemTable(); - CreateCustomerTable(); - CreateHistoryTable(); - CreateStockTable(); - CreateOrdersTable(); - CreateNewOrderTable(); - CreateOrderLineTable(); -} - -///////////////////////////////////////////////////////// -// Load in the tables -///////////////////////////////////////////////////////// - -std::random_device rd; -std::mt19937 rng(rd()); - -// Create random NURand constants, appropriate for loading the database. -NURandConstant::NURandConstant() { - c_last = GetRandomInteger(0, 255); - c_id = GetRandomInteger(0, 1023); - order_line_itme_id = GetRandomInteger(0, 8191); -} - -// A non-uniform random number, as defined by TPC-C 2.1.6. (page 20). -int GetNURand(int a, int x, int y) { - PELOTON_ASSERT(x <= y); - int c = nu_rand_const.c_last; - - if (a == 255) { - c = nu_rand_const.c_last; - } else if (a == 1023) { - c = nu_rand_const.c_id; - } else if (a == 8191) { - c = nu_rand_const.order_line_itme_id; - } else { - PELOTON_ASSERT(false); - } - - return (((GetRandomInteger(0, a) | GetRandomInteger(x, y)) + c) % - (y - x + 1)) + - x; -} - -// A last name as defined by TPC-C 4.3.2.3. Not actually random. -std::string GetLastName(int number) { - PELOTON_ASSERT(number >= 0 && number <= 999); - - int idx1 = number / 100; - int idx2 = (number / 10 % 10); - int idx3 = number % 10; - - char lastname_cstr[name_length]; - std::strcpy(lastname_cstr, syllables[idx1]); - std::strcat(lastname_cstr, syllables[idx2]); - std::strcat(lastname_cstr, syllables[idx3]); - - return std::string(lastname_cstr, name_length); -} - -// A non-uniform random last name, as defined by TPC-C 4.3.2.3. -// The name will be limited to maxCID -std::string GetRandomLastName(int max_cid) { - int min_cid = 999; - if (max_cid - 1 < min_cid) { - min_cid = max_cid - 1; - } - - return GetLastName(GetNURand(255, 0, min_cid)); -} - -std::string GetRandomAlphaNumericString(const size_t string_length) { - const char alphanumeric[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - - std::uniform_int_distribution<> dist(0, sizeof(alphanumeric) - 1); - - char repeated_char = alphanumeric[dist(rng)]; - std::string sample(string_length, repeated_char); - return sample; -} - -bool GetRandomBoolean(double ratio) { - double sample = (double)rand() / RAND_MAX; - return (sample < ratio) ? true : false; -} - -int GetRandomInteger(const int lower_bound, const int upper_bound) { - std::uniform_int_distribution<> dist(lower_bound, upper_bound); - - int sample = dist(rng); - return sample; -} - -int GetRandomIntegerExcluding(const int lower_bound, const int upper_bound, - const int exclude_sample) { - int sample; - if (lower_bound == upper_bound) return lower_bound; - - while (1) { - sample = GetRandomInteger(lower_bound, upper_bound); - if (sample != exclude_sample) break; - } - return sample; -} - -double GetRandomDouble(const double lower_bound, const double upper_bound) { - std::uniform_real_distribution<> dist(lower_bound, upper_bound); - - double sample = dist(rng); - return sample; -} - -double GetRandomFixedPoint(int decimal_places, double minimum, double maximum) { - PELOTON_ASSERT(decimal_places > 0); - PELOTON_ASSERT(minimum < maximum); - - int multiplier = 1; - for (int i = 0; i < decimal_places; ++i) { - multiplier *= 10; - } - - int int_min = (int)(minimum * multiplier + 0.5); - int int_max = (int)(maximum * multiplier + 0.5); - - return GetRandomDouble(int_min, int_max) / (double)(multiplier); -} - -std::string GetStreetName() { - std::vector street_names = { - "5835 Alderson St", "117 Ettwein St", "1400 Fairstead Ln", - "1501 Denniston St", "898 Flemington St", "2325 Eldridge St", - "924 Lilac St", "4299 Minnesota St", "5498 Northumberland St", - "5534 Phillips Ave"}; - - std::uniform_int_distribution<> dist(0, street_names.size() - 1); - return street_names[dist(rng)]; -} - -std::string GetZipCode() { - std::vector zip_codes = {"15215", "14155", "80284", "61845", - "23146", "21456", "12345", "21561", - "87752", "91095"}; - - std::uniform_int_distribution<> dist(0, zip_codes.size() - 1); - return zip_codes[dist(rng)]; -} - -std::string GetCityName() { - std::vector city_names = { - "Madison", "Pittsburgh", "New York", "Seattle", "San Francisco", - "Berkeley", "Palo Alto", "Los Angeles", "Boston", "Redwood Shores"}; - - std::uniform_int_distribution<> dist(0, city_names.size() - 1); - return city_names[dist(rng)]; -} - -std::string GetStateName() { - std::vector state_names = {"WI", "PA", "NY", "WA", "CA", "MA"}; - - std::uniform_int_distribution<> dist(0, state_names.size() - 1); - return state_names[dist(rng)]; -} - -int GetTimeStamp() { - auto time_stamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count(); - return time_stamp; -} - -std::unique_ptr BuildItemTuple( - const int item_id, const std::unique_ptr &pool) { - auto item_table_schema = item_table->GetSchema(); - std::unique_ptr item_tuple( - new storage::Tuple(item_table_schema, allocate)); - - // I_ID - item_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(item_id), nullptr); - // I_IM_ID - item_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(item_id * 10), nullptr); - // I_NAME - auto i_name = GetRandomAlphaNumericString(name_length); - item_tuple->SetValue(2, type::ValueFactory::GetVarcharValue(i_name), pool.get()); - // I_PRICE - double i_price = GetRandomDouble(item_min_price, item_max_price); - item_tuple->SetValue(3, type::ValueFactory::GetDecimalValue(i_price), nullptr); - // I_DATA - auto i_data = GetRandomAlphaNumericString(data_length); - item_tuple->SetValue(4, type::ValueFactory::GetVarcharValue(i_data), pool.get()); - - return item_tuple; -} - -std::unique_ptr BuildWarehouseTuple( - const int warehouse_id, const std::unique_ptr &pool) { - auto warehouse_table_schema = warehouse_table->GetSchema(); - std::unique_ptr warehouse_tuple( - new storage::Tuple(warehouse_table_schema, allocate)); - - // W_ID - warehouse_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // W_NAME - auto w_name = GetRandomAlphaNumericString(warehouse_name_length); - warehouse_tuple->SetValue(1, type::ValueFactory::GetVarcharValue(w_name), - pool.get()); - // W_STREET_1, W_STREET_2 - auto w_street = GetStreetName(); - warehouse_tuple->SetValue(2, type::ValueFactory::GetVarcharValue(w_street), - pool.get()); - warehouse_tuple->SetValue(3, type::ValueFactory::GetVarcharValue(w_street), - pool.get()); - // W_CITY - auto w_city = GetCityName(); - warehouse_tuple->SetValue(4, type::ValueFactory::GetVarcharValue(w_city), - pool.get()); - // W_STATE - auto w_state = GetStateName(); - warehouse_tuple->SetValue(5, type::ValueFactory::GetVarcharValue(w_state), - pool.get()); - // W_ZIP - auto w_zip = GetZipCode(); - warehouse_tuple->SetValue(6, type::ValueFactory::GetVarcharValue(w_zip), pool.get()); - // W_TAX - double w_tax = GetRandomDouble(warehouse_min_tax, warehouse_max_tax); - warehouse_tuple->SetValue(7, type::ValueFactory::GetDecimalValue(w_tax), nullptr); - // W_YTD - warehouse_tuple->SetValue( - 8, type::ValueFactory::GetDecimalValue(warehouse_initial_ytd), nullptr); - - return warehouse_tuple; -} - -std::unique_ptr BuildDistrictTuple( - const int district_id, const int warehouse_id, - const std::unique_ptr &pool) { - auto district_table_schema = district_table->GetSchema(); - std::unique_ptr district_tuple( - new storage::Tuple(district_table_schema, allocate)); - - // D_ID - district_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // D_W_ID - district_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // D_NAME - auto d_name = GetRandomAlphaNumericString(district_name_length); - district_tuple->SetValue(2, type::ValueFactory::GetVarcharValue(d_name), pool.get()); - // D_STREET_1, D_STREET_2 - auto d_street = GetStreetName(); - district_tuple->SetValue(3, type::ValueFactory::GetVarcharValue(d_street), - pool.get()); - district_tuple->SetValue(4, type::ValueFactory::GetVarcharValue(d_street), - pool.get()); - // D_CITY - auto d_city = GetCityName(); - district_tuple->SetValue(5, type::ValueFactory::GetVarcharValue(d_city), pool.get()); - // D_STATE - auto d_state = GetStateName(); - district_tuple->SetValue(6, type::ValueFactory::GetVarcharValue(d_state), - pool.get()); - // D_ZIP - auto d_zip = GetZipCode(); - district_tuple->SetValue(7, type::ValueFactory::GetVarcharValue(d_zip), pool.get()); - // D_TAX - double d_tax = GetRandomDouble(district_min_tax, district_max_tax); - district_tuple->SetValue(8, type::ValueFactory::GetDecimalValue(d_tax), nullptr); - // D_YTD - district_tuple->SetValue( - 9, type::ValueFactory::GetDecimalValue(district_initial_ytd), nullptr); - // D_NEXT_O_ID - auto next_o_id = state.customers_per_district + 1; - district_tuple->SetValue(10, type::ValueFactory::GetIntegerValue(next_o_id), - nullptr); - - return district_tuple; -} - -std::unique_ptr BuildCustomerTuple( - const int customer_id, const int district_id, const int warehouse_id, - const std::unique_ptr &pool) { - // Customer id begins from 0 - PELOTON_ASSERT(customer_id >= 0 && customer_id < state.customers_per_district); - - auto customer_table_schema = customer_table->GetSchema(); - std::unique_ptr customer_tuple( - new storage::Tuple(customer_table_schema, allocate)); - - // C_ID - customer_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(customer_id), - nullptr); - // C_D_ID - customer_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // C_W_ID - customer_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // C_FIRST, C_MIDDLE, C_LAST - auto c_first = GetRandomAlphaNumericString(name_length); - - std::string c_last; - - // Here our customer id begins from 0 - if (customer_id <= 999) { - c_last = GetLastName(customer_id); - } else { - c_last = GetRandomLastName(state.customers_per_district); - } - - auto c_middle = GetRandomAlphaNumericString(middle_name_length); - customer_tuple->SetValue(3, type::ValueFactory::GetVarcharValue(c_first), - pool.get()); - customer_tuple->SetValue(4, type::ValueFactory::GetVarcharValue(c_middle), - pool.get()); - customer_tuple->SetValue(5, type::ValueFactory::GetVarcharValue(c_last), pool.get()); - // C_STREET_1, C_STREET_2 - auto c_street = GetStreetName(); - customer_tuple->SetValue(6, type::ValueFactory::GetVarcharValue(c_street), - pool.get()); - customer_tuple->SetValue(7, type::ValueFactory::GetVarcharValue(c_street), - pool.get()); - // C_CITY - auto c_city = GetCityName(); - customer_tuple->SetValue(8, type::ValueFactory::GetVarcharValue(c_city), pool.get()); - // C_STATE - auto c_state = GetStateName(); - customer_tuple->SetValue(9, type::ValueFactory::GetVarcharValue(c_state), - pool.get()); - // C_ZIP - auto c_zip = GetZipCode(); - customer_tuple->SetValue(10, type::ValueFactory::GetVarcharValue(c_zip), pool.get()); - // C_PHONE - auto c_phone = GetRandomAlphaNumericString(phone_length); - customer_tuple->SetValue(11, type::ValueFactory::GetVarcharValue(c_phone), - pool.get()); - // C_SINCE_TIMESTAMP - auto c_since_timestamp = GetTimeStamp(); - customer_tuple->SetValue( - 12, type::ValueFactory::GetTimestampValue(c_since_timestamp), nullptr); - // C_CREDIT - auto c_bad_credit = GetRandomBoolean(customers_bad_credit_ratio); - auto c_credit = c_bad_credit ? customers_bad_credit : customers_good_credit; - customer_tuple->SetValue(13, type::ValueFactory::GetVarcharValue(c_credit), - pool.get()); - // C_CREDIT_LIM - customer_tuple->SetValue( - 14, type::ValueFactory::GetDecimalValue(customers_init_credit_lim), nullptr); - // C_DISCOUNT - double c_discount = - GetRandomDouble(customers_min_discount, customers_max_discount); - customer_tuple->SetValue(15, type::ValueFactory::GetDecimalValue(c_discount), - nullptr); - // C_BALANCE - customer_tuple->SetValue( - 16, type::ValueFactory::GetDecimalValue(customers_init_balance), nullptr); - // C_YTD_PAYMENT - customer_tuple->SetValue(17, type::ValueFactory::GetDecimalValue(customers_init_ytd), - nullptr); - // C_PAYMENT_CNT - customer_tuple->SetValue( - 18, type::ValueFactory::GetDecimalValue(customers_init_payment_cnt), nullptr); - // C_DELIVERY_CNT - customer_tuple->SetValue( - 19, type::ValueFactory::GetDecimalValue(customers_init_delivery_cnt), nullptr); - // C_DATA - auto c_data = GetRandomAlphaNumericString(data_length); - customer_tuple->SetValue(20, type::ValueFactory::GetVarcharValue(c_data), - pool.get()); - - return customer_tuple; -} - -std::unique_ptr BuildHistoryTuple( - const int customer_id, const int district_id, const int warehouse_id, - const int history_district_id, const int history_warehouse_id, - const std::unique_ptr &pool) { - auto history_table_schema = history_table->GetSchema(); - std::unique_ptr history_tuple( - new storage::Tuple(history_table_schema, allocate)); - - // H_C_ID - history_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(customer_id), - nullptr); - // H_C_D_ID - history_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // H_C_W_ID - history_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // H_D_ID - history_tuple->SetValue(3, type::ValueFactory::GetIntegerValue(history_district_id), - nullptr); - // H_W_ID - history_tuple->SetValue( - 4, type::ValueFactory::GetIntegerValue(history_warehouse_id), nullptr); - // H_DATE - auto h_date = GetTimeStamp(); - history_tuple->SetValue(5, type::ValueFactory::GetTimestampValue(h_date), nullptr); - // H_AMOUNT - history_tuple->SetValue(6, type::ValueFactory::GetDecimalValue(history_init_amount), - nullptr); - // H_DATA - auto h_data = GetRandomAlphaNumericString(history_data_length); - history_tuple->SetValue(7, type::ValueFactory::GetVarcharValue(h_data), pool.get()); - - return history_tuple; -} - -std::unique_ptr BuildOrdersTuple(const int orders_id, - const int district_id, - const int warehouse_id, - const bool new_order, - const int o_ol_cnt) { - auto orders_table_schema = orders_table->GetSchema(); - std::unique_ptr orders_tuple( - new storage::Tuple(orders_table_schema, allocate)); - - // O_ID - orders_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(orders_id), nullptr); - // O_C_ID - auto o_c_id = GetRandomInteger(0, state.customers_per_district); - orders_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(o_c_id), nullptr); - // O_D_ID - orders_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // O_W_ID - orders_tuple->SetValue(3, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // O_ENTRY_D - auto o_entry_d = GetTimeStamp(); - orders_tuple->SetValue(4, type::ValueFactory::GetTimestampValue(o_entry_d), - nullptr); - // O_CARRIER_ID - auto o_carrier_id = orders_null_carrier_id; - if (new_order == false) { - o_carrier_id = - GetRandomInteger(orders_min_carrier_id, orders_max_carrier_id); - } - orders_tuple->SetValue(5, type::ValueFactory::GetIntegerValue(o_carrier_id), - nullptr); - // O_OL_CNT - orders_tuple->SetValue(6, type::ValueFactory::GetIntegerValue(o_ol_cnt), nullptr); - // O_ALL_LOCAL - orders_tuple->SetValue( - 7, type::ValueFactory::GetIntegerValue(orders_init_all_local), nullptr); - - return orders_tuple; -} - -std::unique_ptr BuildNewOrderTuple(const int orders_id, - const int district_id, - const int warehouse_id) { - auto new_order_table_schema = new_order_table->GetSchema(); - std::unique_ptr new_order_tuple( - new storage::Tuple(new_order_table_schema, allocate)); - - // NO_O_ID - new_order_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(orders_id), - nullptr); - // NO_D_ID - new_order_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // NO_W_ID - new_order_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - - return new_order_tuple; -} - -std::unique_ptr BuildOrderLineTuple( - const int orders_id, const int district_id, const int warehouse_id, - const int order_line_id, const int ol_supply_w_id, const bool new_order, - const std::unique_ptr &pool) { - auto order_line_table_schema = order_line_table->GetSchema(); - std::unique_ptr order_line_tuple( - new storage::Tuple(order_line_table_schema, allocate)); - - // OL_O_ID - order_line_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(orders_id), - nullptr); - // OL_D_ID - order_line_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // OL_W_ID - order_line_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // OL_NUMBER - order_line_tuple->SetValue(3, type::ValueFactory::GetIntegerValue(order_line_id), - nullptr); - // OL_I_ID - auto ol_i_id = GetRandomInteger(0, state.item_count); - order_line_tuple->SetValue(4, type::ValueFactory::GetIntegerValue(ol_i_id), - nullptr); - // OL_SUPPLY_W_ID - order_line_tuple->SetValue(5, type::ValueFactory::GetIntegerValue(ol_supply_w_id), - nullptr); - // OL_DELIVERY_D - int64_t ol_delivery_d = GetTimeStamp(); - if (new_order == true) { - ol_delivery_d = type::PELOTON_INT64_MIN; - } - order_line_tuple->SetValue(6, type::ValueFactory::GetTimestampValue(ol_delivery_d), - nullptr); - // OL_QUANTITY - order_line_tuple->SetValue( - 7, type::ValueFactory::GetIntegerValue(order_line_init_quantity), nullptr); - // OL_AMOUNT - double ol_amount = 0; - if (new_order == true) { - ol_amount = GetRandomDouble(order_line_min_amount, - order_line_max_ol_quantity * item_max_price); - } - order_line_tuple->SetValue(8, type::ValueFactory::GetDecimalValue(ol_amount), - nullptr); - // OL_DIST_INFO - auto ol_dist_info = GetRandomAlphaNumericString(order_line_dist_info_length); - order_line_tuple->SetValue(9, type::ValueFactory::GetVarcharValue(ol_dist_info), - pool.get()); - - return order_line_tuple; -} - -std::unique_ptr BuildStockTuple( - const int stock_id, const int s_w_id, - const std::unique_ptr &pool) { - auto stock_table_schema = stock_table->GetSchema(); - std::unique_ptr stock_tuple( - new storage::Tuple(stock_table_schema, allocate)); - - // S_I_ID - stock_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(stock_id), nullptr); - // S_W_ID - stock_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(s_w_id), nullptr); - // S_QUANTITY - auto s_quantity = GetRandomInteger(stock_min_quantity, stock_max_quantity); - stock_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(s_quantity), nullptr); - // S_DIST_01 .. S_DIST_10 - auto s_dist = GetRandomAlphaNumericString(name_length); - stock_tuple->SetValue(3, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(4, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(5, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(6, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(7, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(8, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(9, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(10, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(11, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - stock_tuple->SetValue(12, type::ValueFactory::GetVarcharValue(s_dist), pool.get()); - // S_YTD - auto s_ytd = 0; - stock_tuple->SetValue(13, type::ValueFactory::GetIntegerValue(s_ytd), nullptr); - // S_ORDER_CNT - auto s_order_cnt = 0; - stock_tuple->SetValue(14, type::ValueFactory::GetIntegerValue(s_order_cnt), - nullptr); - // S_REMOTE_CNT - auto s_remote_cnt = 0; - stock_tuple->SetValue(15, type::ValueFactory::GetIntegerValue(s_remote_cnt), - nullptr); - // S_DATA - auto s_data = GetRandomAlphaNumericString(data_length); - stock_tuple->SetValue(16, type::ValueFactory::GetVarcharValue(s_data), pool.get()); - - return stock_tuple; -} - -void LoadItems() { - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto txn = txn_manager.BeginTransaction(); - std::unique_ptr pool(new type::EphemeralPool()); - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - for (auto item_itr = 0; item_itr < state.item_count; item_itr++) { - auto item_tuple = BuildItemTuple(item_itr, pool); - planner::InsertPlan node(item_table, std::move(item_tuple)); - executor::InsertExecutor executor(&node, context.get()); - executor.Execute(); - } - - txn_manager.CommitTransaction(txn); -} - -void LoadWarehouses(const int &warehouse_from, const int &warehouse_to) { - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - std::unique_ptr context; - - // WAREHOUSES - for (auto warehouse_itr = warehouse_from; warehouse_itr < warehouse_to; warehouse_itr++) { - - std::unique_ptr pool(new type::EphemeralPool()); - - auto txn = txn_manager.BeginTransaction(); - context.reset(new executor::ExecutorContext(txn)); - - auto warehouse_tuple = BuildWarehouseTuple(warehouse_itr, pool); - planner::InsertPlan warehouse_node(warehouse_table, - std::move(warehouse_tuple)); - executor::InsertExecutor warehouse_executor(&warehouse_node, context.get()); - warehouse_executor.Execute(); - - txn_manager.CommitTransaction(txn); - - // DISTRICTS - for (auto district_itr = 0; district_itr < state.districts_per_warehouse; - district_itr++) { - auto txn = txn_manager.BeginTransaction(); - context.reset(new executor::ExecutorContext(txn)); - - auto district_tuple = - BuildDistrictTuple(district_itr, warehouse_itr, pool); - planner::InsertPlan district_node(district_table, - std::move(district_tuple)); - executor::InsertExecutor district_executor(&district_node, context.get()); - district_executor.Execute(); - - txn_manager.CommitTransaction(txn); - - // CUSTOMERS - for (auto customer_itr = 0; customer_itr < state.customers_per_district; - customer_itr++) { - auto txn = txn_manager.BeginTransaction(); - context.reset(new executor::ExecutorContext(txn)); - - auto customer_tuple = - BuildCustomerTuple(customer_itr, district_itr, warehouse_itr, pool); - planner::InsertPlan customer_node(customer_table, - std::move(customer_tuple)); - executor::InsertExecutor customer_executor(&customer_node, - context.get()); - customer_executor.Execute(); - - // HISTORY - - int history_district_id = district_itr; - int history_warehouse_id = warehouse_itr; - auto history_tuple = - BuildHistoryTuple(customer_itr, district_itr, warehouse_itr, - history_district_id, history_warehouse_id, pool); - planner::InsertPlan history_node(history_table, - std::move(history_tuple)); - executor::InsertExecutor history_executor(&history_node, context.get()); - history_executor.Execute(); - - txn_manager.CommitTransaction(txn); - - } // END CUSTOMERS - - // ORDERS - for (auto orders_itr = 0; orders_itr < state.customers_per_district; - orders_itr++) { - auto txn = txn_manager.BeginTransaction(); - context.reset(new executor::ExecutorContext(txn)); - - // New order ? - auto new_order_threshold = - state.customers_per_district - new_orders_per_district; - bool new_order = (orders_itr > new_order_threshold); - auto o_ol_cnt = GetRandomInteger(orders_min_ol_cnt, orders_max_ol_cnt); - - auto orders_tuple = BuildOrdersTuple( - orders_itr, district_itr, warehouse_itr, new_order, o_ol_cnt); - planner::InsertPlan orders_node(orders_table, std::move(orders_tuple)); - executor::InsertExecutor orders_executor(&orders_node, context.get()); - orders_executor.Execute(); - - // NEW_ORDER - if (new_order) { - auto new_order_tuple = - BuildNewOrderTuple(orders_itr, district_itr, warehouse_itr); - planner::InsertPlan new_order_node(new_order_table, - std::move(new_order_tuple)); - executor::InsertExecutor new_order_executor(&new_order_node, - context.get()); - new_order_executor.Execute(); - } - - // ORDER_LINE - for (auto order_line_itr = 0; order_line_itr < o_ol_cnt; - order_line_itr++) { - int ol_supply_w_id = warehouse_itr; - auto order_line_tuple = BuildOrderLineTuple( - orders_itr, district_itr, warehouse_itr, order_line_itr, - ol_supply_w_id, new_order, pool); - planner::InsertPlan order_line_node(order_line_table, - std::move(order_line_tuple)); - executor::InsertExecutor order_line_executor(&order_line_node, - context.get()); - order_line_executor.Execute(); - } - - txn_manager.CommitTransaction(txn); - } - - } // END DISTRICTS - - // STOCK - for (auto stock_itr = 0; stock_itr < state.item_count; stock_itr++) { - auto txn = txn_manager.BeginTransaction(); - context.reset(new executor::ExecutorContext(txn)); - - int s_w_id = warehouse_itr; - auto stock_tuple = BuildStockTuple(stock_itr, s_w_id, pool); - planner::InsertPlan stock_node(stock_table, std::move(stock_tuple)); - executor::InsertExecutor stock_executor(&stock_node, context.get()); - stock_executor.Execute(); - - txn_manager.CommitTransaction(txn); - } - - } // END WAREHOUSES -} - -void LoadTPCCDatabase() { - - std::chrono::steady_clock::time_point start_time; - start_time = std::chrono::steady_clock::now(); - - LoadItems(); - - if (state.warehouse_count < state.loader_count) { - std::vector> load_threads(state.warehouse_count); - for (int thread_id = 0; thread_id < state.warehouse_count; ++thread_id) { - int warehouse_from = thread_id; - int warehouse_to = thread_id + 1; - load_threads[thread_id].reset(new std::thread(LoadWarehouses, warehouse_from, warehouse_to)); - } - - for (auto thread_id = 0; thread_id < state.warehouse_count; ++thread_id) { - load_threads[thread_id]->join(); - } - - } else { - std::vector> load_threads(state.loader_count); - int warehouse_per_thread = state.warehouse_count / state.loader_count; - for (int thread_id = 0; thread_id < state.loader_count - 1; ++thread_id) { - int warehouse_from = warehouse_per_thread * thread_id; - int warehouse_to = warehouse_per_thread * (thread_id + 1); - load_threads[thread_id].reset(new std::thread(LoadWarehouses, warehouse_from, warehouse_to)); - } - int thread_id = state.loader_count - 1; - int warehouse_from = warehouse_per_thread * thread_id; - int warehouse_to = state.warehouse_count; - load_threads[thread_id].reset(new std::thread(LoadWarehouses, warehouse_from, warehouse_to)); - - for (auto thread_id = 0; thread_id < state.loader_count; ++thread_id) { - load_threads[thread_id]->join(); - } - } - - std::chrono::steady_clock::time_point end_time = std::chrono::steady_clock::now(); - UNUSED_ATTRIBUTE double diff = std::chrono::duration_cast(end_time - start_time).count(); - LOG_INFO("database loading time = %lf ms", diff); - - LOG_INFO("%sTABLE SIZES%s", peloton::GETINFO_HALF_THICK_LINE.c_str(), peloton::GETINFO_HALF_THICK_LINE.c_str()); - LOG_INFO("warehouse count = %lu", warehouse_table->GetTupleCount()); - LOG_INFO("district count = %lu", district_table->GetTupleCount()); - LOG_INFO("item count = %lu", item_table->GetTupleCount()); - LOG_INFO("customer count = %lu", customer_table->GetTupleCount()); - LOG_INFO("history count = %lu", history_table->GetTupleCount()); - LOG_INFO("stock count = %lu", stock_table->GetTupleCount()); - LOG_INFO("orders count = %lu", orders_table->GetTupleCount()); - LOG_INFO("new order count = %lu", new_order_table->GetTupleCount()); - LOG_INFO("order line count = %lu", order_line_table->GetTupleCount()); -} - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton - -#ifdef __APPLE__ -#pragma clang diagnostic pop -#endif \ No newline at end of file diff --git a/src/main/tpcc/tpcc_new_order.cpp b/src/main/tpcc/tpcc_new_order.cpp deleted file mode 100644 index 5ba66431355..00000000000 --- a/src/main/tpcc/tpcc_new_order.cpp +++ /dev/null @@ -1,732 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_new_order.cpp -// -// Identification: src/main/tpcc/tpcc_new_order.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_workload.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/generator.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/timer.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/executor_context.h" -#include "executor/index_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/update_executor.h" - -#include "common/container_tuple.h" -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/tuple_value_expression.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/materialization_plan.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -bool RunNewOrder(const size_t &thread_id) { - /* - "NEW_ORDER": { - "getWarehouseTaxRate": "SELECT W_TAX FROM WAREHOUSE WHERE W_ID = ?", # w_id - "getDistrict": "SELECT D_TAX, D_NEXT_O_ID FROM DISTRICT WHERE D_ID = ? AND - D_W_ID = ?", # d_id, w_id - "getCustomer": "SELECT C_DISCOUNT, C_LAST, C_CREDIT FROM CUSTOMER WHERE - C_W_ID = ? AND C_D_ID = ? AND C_ID = ?", # w_id, d_id, c_id - "incrementNextOrderId": "UPDATE DISTRICT SET D_NEXT_O_ID = ? WHERE D_ID = ? - AND D_W_ID = ?", # d_next_o_id, d_id, w_id - "createOrder": "INSERT INTO ORDERS (O_ID, O_D_ID, O_W_ID, O_C_ID, - O_ENTRY_D, O_CARRIER_ID, O_OL_CNT, O_ALL_LOCAL) VALUES (?, ?, ?, ?, ?, ?, - ?, ?)", # d_next_o_id, d_id, w_id, c_id, o_entry_d, o_carrier_id, o_ol_cnt, - o_all_local - "createNewOrder": "INSERT INTO NEW_ORDER (NO_O_ID, NO_D_ID, NO_W_ID) VALUES - (?, ?, ?)", # o_id, d_id, w_id - "getItemInfo": "SELECT I_PRICE, I_NAME, I_DATA FROM ITEM WHERE I_ID = ?", # - ol_i_id - "getStockInfo": "SELECT S_QUANTITY, S_DATA, S_YTD, S_ORDER_CNT, - S_REMOTE_CNT, S_DIST_%02d FROM STOCK WHERE S_I_ID = ? AND S_W_ID = ?", # - d_id, ol_i_id, ol_supply_w_id - "updateStock": "UPDATE STOCK SET S_QUANTITY = ?, S_YTD = ?, S_ORDER_CNT = - ?, S_REMOTE_CNT = ? WHERE S_I_ID = ? AND S_W_ID = ?", # s_quantity, - s_order_cnt, s_remote_cnt, ol_i_id, ol_supply_w_id - "createOrderLine": "INSERT INTO ORDER_LINE (OL_O_ID, OL_D_ID, OL_W_ID, - OL_NUMBER, OL_I_ID, OL_SUPPLY_W_ID, OL_DELIVERY_D, OL_QUANTITY, OL_AMOUNT, - OL_DIST_INFO) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", # o_id, d_id, w_id, - ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info - } - */ - - LOG_TRACE("-------------------------------------"); - - ///////////////////////////////////////////////////////// - // PREPARE ARGUMENTS - ///////////////////////////////////////////////////////// - int warehouse_id = GenerateWarehouseId(thread_id); - int district_id = GetRandomInteger(0, state.districts_per_warehouse - 1); - int customer_id = GetRandomInteger(0, state.customers_per_district - 1); - int o_ol_cnt = GetRandomInteger(orders_min_ol_cnt, orders_max_ol_cnt); - - std::vector i_ids, ol_w_ids, ol_qtys; - bool o_all_local = true; - - for (auto ol_itr = 0; ol_itr < o_ol_cnt; ol_itr++) { - // in the original TPC-C benchmark, it is possible to read an item that does - // not exist. - // for simplicity, we ignore this case. - // this essentially makes the processing of NewOrder transaction more - // time-consuming. - i_ids.push_back(GetRandomInteger(0, state.item_count - 1)); - bool remote = GetRandomBoolean(new_order_remote_txns); - ol_w_ids.push_back(warehouse_id); - - if (remote == true) { - ol_w_ids[ol_itr] = - GetRandomIntegerExcluding(0, state.warehouse_count - 1, warehouse_id); - o_all_local = false; - } - - ol_qtys.push_back(GetRandomInteger(0, order_line_max_ol_quantity)); - } - - std::vector runtime_keys; - - ///////////////////////////////////////////////////////// - // BEGIN TRANSACTION - ///////////////////////////////////////////////////////// - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - auto txn = txn_manager.BeginTransaction(thread_id); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - std::vector item_key_column_ids; - std::vector item_expr_types; - item_key_column_ids.push_back(0); // I_ID - item_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector item_column_ids = {2, 3, 4}; // I_NAME, I_PRICE, I_DATA - - for (auto item_id : i_ids) { - LOG_TRACE( - "getItemInfo: SELECT I_PRICE, I_NAME, I_DATA FROM ITEM WHERE I_ID = %d", - item_id); - - std::vector item_key_values; - - item_key_values.push_back( - type::ValueFactory::GetIntegerValue(item_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc item_index_scan_desc( - item_table_pkey_index_oid, item_key_column_ids, item_expr_types, - item_key_values, runtime_keys); - - planner::IndexScanPlan item_index_scan_node( - item_table, nullptr, item_column_ids, item_index_scan_desc); - - executor::IndexScanExecutor item_index_scan_executor(&item_index_scan_node, - context.get()); - - auto gii_lists_values = ExecuteRead(&item_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (gii_lists_values.size() != 1) { - LOG_ERROR("getItemInfo return size incorrect : %lu", - gii_lists_values.size()); - PELOTON_ASSERT(false); - } - } - - LOG_TRACE("getWarehouseTaxRate: SELECT W_TAX FROM WAREHOUSE WHERE W_ID = %d", - warehouse_id); - - std::vector warehouse_key_column_ids; - std::vector warehouse_expr_types; - warehouse_key_column_ids.push_back(0); // W_ID - warehouse_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector warehouse_key_values; - - warehouse_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc warehouse_index_scan_desc( - warehouse_table_pkey_index_oid, warehouse_key_column_ids, - warehouse_expr_types, warehouse_key_values, runtime_keys); - - std::vector warehouse_column_ids = {7}; // W_TAX - - planner::IndexScanPlan warehouse_index_scan_node(warehouse_table, nullptr, - warehouse_column_ids, - warehouse_index_scan_desc); - - executor::IndexScanExecutor warehouse_index_scan_executor( - &warehouse_index_scan_node, context.get()); - - auto gwtr_lists_values = ExecuteRead(&warehouse_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (gwtr_lists_values.size() != 1) { - LOG_ERROR("getWarehouseTaxRate return size incorrect : %lu", - gwtr_lists_values.size()); - PELOTON_ASSERT(false); - } - - UNUSED_ATTRIBUTE auto w_tax = gwtr_lists_values[0][0]; - - LOG_TRACE("w_tax: %s", w_tax.GetInfo().c_str()); - - LOG_TRACE( - "getDistrict: SELECT D_TAX, D_NEXT_O_ID FROM DISTRICT WHERE D_ID = %d " - "AND D_W_ID = %d", - district_id, warehouse_id); - - std::vector district_key_column_ids; - std::vector district_expr_types; - - district_key_column_ids.push_back(0); // D_ID - district_key_column_ids.push_back(1); // D_W_ID - district_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - district_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector district_key_values; - district_key_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - district_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc district_index_scan_desc( - district_table_pkey_index_oid, district_key_column_ids, - district_expr_types, district_key_values, runtime_keys); - - std::vector district_column_ids = {8, 10}; // D_TAX, D_NEXT_O_ID - - // Create plan node. - planner::IndexScanPlan district_index_scan_node( - district_table, nullptr, district_column_ids, district_index_scan_desc); - - executor::IndexScanExecutor district_index_scan_executor( - &district_index_scan_node, context.get()); - - auto gd_lists_values = ExecuteRead(&district_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (gd_lists_values.size() != 1) { - LOG_ERROR("getDistrict return size incorrect : %lu", - gd_lists_values.size()); - PELOTON_ASSERT(false); - } - - UNUSED_ATTRIBUTE auto d_tax = gd_lists_values[0][0]; - UNUSED_ATTRIBUTE auto d_next_o_id = gd_lists_values[0][1]; - - LOG_TRACE("d_tax: %s, d_next_o_id: %s", d_tax.GetInfo().c_str(), - d_next_o_id.GetInfo().c_str()); - - LOG_TRACE( - "getCustomer: SELECT C_DISCOUNT, C_LAST, C_CREDIT FROM CUSTOMER WHERE " - "C_W_ID = %d AND C_D_ID = %d AND C_ID = %d", - warehouse_id, district_id, customer_id); - - std::vector customer_key_column_ids; - std::vector customer_expr_types; - - customer_key_column_ids.push_back(0); // C_ID - customer_key_column_ids.push_back(1); // C_D_ID - customer_key_column_ids.push_back(2); // C_W_ID - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector customer_key_values; - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(customer_id).Copy()); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_index_scan_desc( - customer_table_pkey_index_oid, customer_key_column_ids, - customer_expr_types, customer_key_values, runtime_keys); - - std::vector customer_column_ids = { - 5, 13, 15}; // C_LAST, C_CREDIT, C_DISCOUNT - - // Create plan node. - planner::IndexScanPlan customer_index_scan_node( - customer_table, nullptr, customer_column_ids, customer_index_scan_desc); - - executor::IndexScanExecutor customer_index_scan_executor( - &customer_index_scan_node, context.get()); - - auto gc_lists_values = ExecuteRead(&customer_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (gc_lists_values.size() != 1) { - LOG_ERROR("getCustomer return size incorrect : %lu", - gc_lists_values.size()); - PELOTON_ASSERT(false); - } - - UNUSED_ATTRIBUTE auto c_last = gc_lists_values[0][0]; - UNUSED_ATTRIBUTE auto c_credit = gc_lists_values[0][1]; - UNUSED_ATTRIBUTE auto c_discount = gc_lists_values[0][2]; - - LOG_TRACE("c_last: %s, c_credit: %s, c_discount: %s", - c_last.GetInfo().c_str(), c_credit.GetInfo().c_str(), - c_discount.GetInfo().c_str()); - - int district_update_value = type::ValuePeeker::PeekInteger(d_next_o_id) + 1; - LOG_TRACE("district update value = %d", district_update_value); - - LOG_TRACE( - "incrementNextOrderId: UPDATE DISTRICT SET D_NEXT_O_ID = %d WHERE D_ID = " - "%d AND D_W_ID = %d", - district_update_value, district_id, warehouse_id); - - std::vector district_update_column_ids = {10}; // D_NEXT_O_ID - - std::vector district_update_key_values; - district_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - district_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc district_update_index_scan_desc( - district_table_pkey_index_oid, district_key_column_ids, - district_expr_types, district_update_key_values, runtime_keys); - - // Create plan node. - planner::IndexScanPlan district_update_index_scan_node( - district_table, nullptr, district_update_column_ids, - district_update_index_scan_desc); - - executor::IndexScanExecutor district_update_index_scan_executor( - &district_update_index_scan_node, context.get()); - - TargetList district_target_list; - DirectMapList district_direct_map_list; - - // Update the last attribute - for (oid_t col_itr = 0; col_itr < 10; col_itr++) { - district_direct_map_list.emplace_back(col_itr, - std::pair(0, col_itr)); - } - type::Value district_update_val = - type::ValueFactory::GetIntegerValue(district_update_value).Copy(); - - planner::DerivedAttribute attribute{ - expression::ExpressionUtil::ConstantValueFactory(district_update_val)}; - district_target_list.emplace_back(10, attribute); - - std::unique_ptr district_project_info( - new planner::ProjectInfo(std::move(district_target_list), - std::move(district_direct_map_list))); - planner::UpdatePlan district_update_node(district_table, - std::move(district_project_info)); - - executor::UpdateExecutor district_update_executor(&district_update_node, - context.get()); - - district_update_executor.AddChild(&district_update_index_scan_executor); - - ExecuteUpdate(&district_update_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - LOG_TRACE( - "createOrder: INSERT INTO ORDERS (O_ID, O_D_ID, O_W_ID, O_C_ID, " - "O_ENTRY_D, O_CARRIER_ID, O_OL_CNT, O_ALL_LOCAL)"); - - std::unique_ptr orders_tuple( - new storage::Tuple(orders_table->GetSchema(), true)); - - // O_ID - orders_tuple->SetValue(0, type::ValueFactory::GetIntegerValue( - type::ValuePeeker::PeekInteger(d_next_o_id)), - nullptr); - // O_C_ID - orders_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(customer_id), - nullptr); - // O_D_ID - orders_tuple->SetValue(2, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // O_W_ID - orders_tuple->SetValue(3, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // O_ENTRY_D - // auto o_entry_d = GetTimeStamp(); - orders_tuple->SetValue(4, type::ValueFactory::GetTimestampValue(1), nullptr); - // O_CARRIER_ID - orders_tuple->SetValue(5, type::ValueFactory::GetIntegerValue(0), nullptr); - // O_OL_CNT - orders_tuple->SetValue(6, type::ValueFactory::GetIntegerValue(o_ol_cnt), - nullptr); - // O_ALL_LOCAL - orders_tuple->SetValue(7, type::ValueFactory::GetIntegerValue(o_all_local), - nullptr); - - planner::InsertPlan orders_node(orders_table, std::move(orders_tuple)); - executor::InsertExecutor orders_executor(&orders_node, context.get()); - orders_executor.Execute(); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE( - "abort transaction when inserting order table, thread_id = %d, d_id = " - "%d, next_o_id = %d", - (int)thread_id, (int)district_id, - (int)type::ValuePeeker::PeekInteger(d_next_o_id)); - txn_manager.AbortTransaction(txn); - return false; - } else { - LOG_TRACE( - "successfully insert order table, thread_id = %d, d_id = %d, next_o_id " - "= %d", - (int)thread_id, (int)district_id, - (int)type::ValuePeeker::PeekInteger(d_next_o_id)); - } - - LOG_TRACE( - "createNewOrder: INSERT INTO NEW_ORDER (NO_O_ID, NO_D_ID, NO_W_ID) " - "VALUES (?, ?, ?)"); - std::unique_ptr new_order_tuple( - new storage::Tuple(new_order_table->GetSchema(), true)); - - // NO_O_ID - new_order_tuple->SetValue(0, type::ValueFactory::GetIntegerValue( - type::ValuePeeker::PeekInteger(d_next_o_id)), - nullptr); - // NO_D_ID - new_order_tuple->SetValue(1, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // NO_W_ID - new_order_tuple->SetValue( - 2, type::ValueFactory::GetIntegerValue(warehouse_id), nullptr); - - planner::InsertPlan new_order_node(new_order_table, - std::move(new_order_tuple)); - executor::InsertExecutor new_order_executor(&new_order_node, context.get()); - new_order_executor.Execute(); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction when inserting new order table"); - txn_manager.AbortTransaction(txn); - return false; - } - - std::vector stock_key_column_ids; - std::vector stock_expr_types; - - stock_key_column_ids.push_back(0); // S_I_ID - stock_key_column_ids.push_back(1); // S_W_ID - stock_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - stock_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - auto stock_pkey_index = - stock_table->GetIndexWithOid(stock_table_pkey_index_oid); - - // S_QUANTITY, S_DIST_%02d, S_YTD, S_ORDER_CNT, S_REMOTE_CNT, S_DATA - std::vector stock_column_ids = {2, oid_t(3 + district_id), 13, 14, 15, - 16}; - - std::vector stock_update_column_ids = { - 2, 13, 14, 15}; // S_QUANTITY, S_YTD, S_ORDER_CNT, S_REMOTE_CNT - - for (size_t i = 0; i < i_ids.size(); ++i) { - int item_id = i_ids.at(i); - int ol_w_id = ol_w_ids.at(i); - int ol_qty = ol_qtys.at(i); - - LOG_TRACE( - "getStockInfo: SELECT S_QUANTITY, S_DATA, S_YTD, S_ORDER_CNT, " - "S_REMOTE_CNT, S_DIST_? FROM STOCK WHERE S_I_ID = %d AND S_W_ID = %d", - item_id, ol_w_id); - - std::vector stock_key_values; - - stock_key_values.push_back( - type::ValueFactory::GetIntegerValue(item_id).Copy()); - stock_key_values.push_back( - type::ValueFactory::GetIntegerValue(ol_w_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc stock_index_scan_desc( - stock_table_pkey_index_oid, stock_key_column_ids, stock_expr_types, - stock_key_values, runtime_keys); - - std::vector stock_update_key_values; - - stock_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(item_id).Copy()); - stock_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(ol_w_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc stock_update_index_scan_desc( - stock_table_pkey_index_oid, stock_key_column_ids, stock_expr_types, - stock_update_key_values, runtime_keys); - - // Create plan node. - planner::IndexScanPlan stock_index_scan_node( - stock_table, nullptr, stock_column_ids, stock_index_scan_desc); - - executor::IndexScanExecutor stock_index_scan_executor( - &stock_index_scan_node, context.get()); - - auto gsi_lists_values = ExecuteRead(&stock_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (gsi_lists_values.size() != 1) { - LOG_ERROR("getStockInfo return size incorrect : %lu", - gsi_lists_values.size()); - PELOTON_ASSERT(false); - } - - int s_quantity = type::ValuePeeker::PeekInteger(gsi_lists_values[0][0]); - - if (s_quantity >= ol_qty + 10) { - s_quantity = s_quantity - ol_qty; - } else { - s_quantity = s_quantity + 91 - ol_qty; - } - - type::Value s_data = gsi_lists_values[0][1]; - - int s_ytd = type::ValuePeeker::PeekInteger(gsi_lists_values[0][2]) + ol_qty; - - int s_order_cnt = - type::ValuePeeker::PeekInteger(gsi_lists_values[0][3]) + 1; - - int s_remote_cnt = type::ValuePeeker::PeekInteger(gsi_lists_values[0][4]); - - if (ol_w_id != warehouse_id) { - s_remote_cnt += 1; - } - - LOG_TRACE( - "updateStock: UPDATE STOCK SET S_QUANTITY = ?, S_YTD = ?, S_ORDER_CNT " - "= ?, S_REMOTE_CNT = ? WHERE S_I_ID = ? AND S_W_ID = ?"); - - // Create plan node. - planner::IndexScanPlan stock_update_index_scan_node( - stock_table, nullptr, stock_update_column_ids, - stock_update_index_scan_desc); - - executor::IndexScanExecutor stock_update_index_scan_executor( - &stock_update_index_scan_node, context.get()); - - TargetList stock_target_list; - DirectMapList stock_direct_map_list; - - // Update the last attribute - for (oid_t col_itr = 0; col_itr < 17; col_itr++) { - if (col_itr != 2 && col_itr != 13 && col_itr != 14 && col_itr != 15) { - stock_direct_map_list.emplace_back(col_itr, - std::pair(0, col_itr)); - } - } - planner::DerivedAttribute s_quantity_attr{ - expression::ExpressionUtil::ConstantValueFactory( - type::ValueFactory::GetIntegerValue(s_quantity))}; - - planner::DerivedAttribute s_ytd_attr{ - expression::ExpressionUtil::ConstantValueFactory( - type::ValueFactory::GetIntegerValue(s_ytd))}; - - planner::DerivedAttribute s_order_cnt_attr{ - expression::ExpressionUtil::ConstantValueFactory( - type::ValueFactory::GetIntegerValue(s_order_cnt))}; - - planner::DerivedAttribute s_remote_cnt_attr{ - expression::ExpressionUtil::ConstantValueFactory( - type::ValueFactory::GetIntegerValue(s_remote_cnt))}; - - stock_target_list.emplace_back(2, s_quantity_attr); - stock_target_list.emplace_back(13, s_ytd_attr); - stock_target_list.emplace_back(14, s_order_cnt_attr); - stock_target_list.emplace_back(15, s_remote_cnt_attr); - - std::unique_ptr stock_project_info( - new planner::ProjectInfo(std::move(stock_target_list), - std::move(stock_direct_map_list))); - planner::UpdatePlan stock_update_node(stock_table, - std::move(stock_project_info)); - - executor::UpdateExecutor stock_update_executor(&stock_update_node, - context.get()); - - stock_update_executor.AddChild(&stock_update_index_scan_executor); - - ExecuteUpdate(&stock_update_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - // the original benchmark requires check constraints. - // however, we ignored here. - // it does not influence the performance. - // if i_data.find(constants.ORIGINAL_STRING) != -1 and - // s_data.find(constants.ORIGINAL_STRING) != -1: - // brand_generic = 'B' - // else: - // brand_generic = 'G' - - LOG_TRACE( - "createOrderLine: INSERT INTO ORDER_LINE (OL_O_ID, OL_D_ID, OL_W_ID, " - "OL_NUMBER, OL_I_ID, OL_SUPPLY_W_ID, OL_DELIVERY_D, OL_QUANTITY, " - "OL_AMOUNT, OL_DIST_INFO) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - std::unique_ptr order_line_tuple( - new storage::Tuple(order_line_table->GetSchema(), true)); - - // OL_O_ID - order_line_tuple->SetValue(0, - type::ValueFactory::GetIntegerValue( - type::ValuePeeker::PeekInteger(d_next_o_id)), - nullptr); - // OL_D_ID - order_line_tuple->SetValue( - 1, type::ValueFactory::GetIntegerValue(district_id), nullptr); - // OL_W_ID - order_line_tuple->SetValue( - 2, type::ValueFactory::GetIntegerValue(warehouse_id), nullptr); - // OL_NUMBER - order_line_tuple->SetValue(3, type::ValueFactory::GetIntegerValue(i), - nullptr); - // OL_I_ID - order_line_tuple->SetValue(4, type::ValueFactory::GetIntegerValue(item_id), - nullptr); - // OL_SUPPLY_W_ID - order_line_tuple->SetValue(5, type::ValueFactory::GetIntegerValue(ol_w_id), - nullptr); - // OL_DELIVERY_D - order_line_tuple->SetValue(6, type::ValueFactory::GetTimestampValue(1), - nullptr); - // OL_QUANTITY - order_line_tuple->SetValue(7, type::ValueFactory::GetIntegerValue(ol_qty), - nullptr); - // OL_AMOUNT - // TODO: workaround!!! I don't know how to get float from Value. - order_line_tuple->SetValue(8, type::ValueFactory::GetDecimalValue(0), - nullptr); - // OL_DIST_INFO - order_line_tuple->SetValue(9, s_data, nullptr); - - planner::InsertPlan order_line_node(order_line_table, - std::move(order_line_tuple)); - executor::InsertExecutor order_line_executor(&order_line_node, - context.get()); - order_line_executor.Execute(); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction when inserting order line table"); - txn_manager.AbortTransaction(txn); - return false; - } - } - - // transaction passed execution. - PELOTON_ASSERT(txn->GetResult() == ResultType::SUCCESS); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - // transaction passed commitment. - LOG_TRACE("commit txn, thread_id = %d, d_id = %d, next_o_id = %d", - (int)thread_id, (int)district_id, - (int)type::ValuePeeker::PeekInteger(d_next_o_id)); - return true; - - } else { - // transaction failed commitment. - PELOTON_ASSERT(result == ResultType::ABORTED || - result == ResultType::FAILURE); - LOG_TRACE("abort txn, thread_id = %d, d_id = %d, next_o_id = %d", - (int)thread_id, (int)district_id, - (int)type::ValuePeeker::PeekInteger(d_next_o_id)); - return false; - } -} -} -} -} diff --git a/src/main/tpcc/tpcc_order_status.cpp b/src/main/tpcc/tpcc_order_status.cpp deleted file mode 100644 index 8628f5e8345..00000000000 --- a/src/main/tpcc/tpcc_order_status.cpp +++ /dev/null @@ -1,354 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_order_status.cpp -// -// Identification: src/main/tpcc/tpcc_order_status.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_workload.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/generator.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/timer.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/executor_context.h" -#include "executor/index_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/limit_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/order_by_executor.h" -#include "executor/update_executor.h" - -#include "common/container_tuple.h" -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/tuple_value_expression.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/limit_plan.h" -#include "planner/materialization_plan.h" -#include "planner/order_by_plan.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -bool RunOrderStatus(const size_t &thread_id) { - /* - "ORDER_STATUS": { - "getCustomerByCustomerId": "SELECT C_ID, C_FIRST, C_MIDDLE, C_LAST, - C_BALANCE FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ?", # - w_id, d_id, c_id - "getCustomersByLastName": "SELECT C_ID, C_FIRST, C_MIDDLE, C_LAST, C_BALANCE - FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_LAST = ? ORDER BY - C_FIRST", # w_id, d_id, c_last - "getLastOrder": "SELECT O_ID, O_CARRIER_ID, O_ENTRY_D FROM ORDERS WHERE - O_W_ID = ? AND O_D_ID = ? AND O_C_ID = ? ORDER BY O_ID DESC LIMIT 1", # - w_id, d_id, c_id - "getOrderLines": "SELECT OL_SUPPLY_W_ID, OL_I_ID, OL_QUANTITY, OL_AMOUNT, - OL_DELIVERY_D FROM ORDER_LINE WHERE OL_W_ID = ? AND OL_D_ID = ? AND OL_O_ID - = ?", # w_id, d_id, o_id - } - */ - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto txn = txn_manager.BeginTransaction(thread_id); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - // Generate w_id, d_id, c_id, c_last - // int w_id = GetRandomInteger(0, state.warehouse_count - 1); - int w_id = GenerateWarehouseId(thread_id); - int d_id = GetRandomInteger(0, state.districts_per_warehouse - 1); - - int c_id = -1; - std::string c_last; - - // if (GetRandomInteger(1, 100) <= 60) { - // c_last = GetRandomLastName(state.customers_per_district); - // } else { - c_id = GetNURand(1023, 0, state.customers_per_district - 1); - // } - - // Run queries - if (c_id != -1) { - LOG_TRACE( - "getCustomerByCustomerId: SELECT C_ID, C_FIRST, C_MIDDLE, C_LAST, " - "C_BALANCE FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? " - "# w_id, d_id, c_id"); - // Construct index scan executor - std::vector customer_column_ids = {COL_IDX_C_ID, COL_IDX_C_FIRST, - COL_IDX_C_MIDDLE, COL_IDX_C_LAST, - COL_IDX_C_BALANCE}; - std::vector customer_key_column_ids = {COL_IDX_C_W_ID, - COL_IDX_C_D_ID, COL_IDX_C_ID}; - std::vector customer_expr_types; - std::vector customer_key_values; - std::vector runtime_keys; - - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(w_id).Copy()); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(c_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_index_scan_desc( - customer_table_pkey_index_oid, customer_key_column_ids, - customer_expr_types, customer_key_values, runtime_keys); - - auto predicate = nullptr; - planner::IndexScanPlan customer_index_scan_node(customer_table, predicate, - customer_column_ids, - customer_index_scan_desc); - - executor::IndexScanExecutor customer_index_scan_executor( - &customer_index_scan_node, context.get()); - - auto result = ExecuteRead(&customer_index_scan_executor); - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - - if (result.size() == 0) { - LOG_ERROR("wrong result size : %lu", result.size()); - PELOTON_ASSERT(false); - } - if (result[0].size() == 0) { - LOG_ERROR("wrong result[0] size : %lu", result[0].size()); - PELOTON_ASSERT(false); - } - } else { - LOG_ERROR( - "getCustomersByLastName: SELECT C_ID, C_FIRST, C_MIDDLE, C_LAST, " - "C_BALANCE FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_LAST = " - "? ORDER BY C_FIRST, # w_id, d_id, c_last"); - // Construct index scan executor - std::vector customer_column_ids = {COL_IDX_C_ID, COL_IDX_C_FIRST, - COL_IDX_C_MIDDLE, COL_IDX_C_LAST, - COL_IDX_C_BALANCE}; - std::vector customer_key_column_ids = { - COL_IDX_C_W_ID, COL_IDX_C_D_ID, COL_IDX_C_LAST}; - std::vector customer_expr_types; - std::vector customer_key_values; - std::vector runtime_keys; - - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(w_id).Copy()); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_key_values.push_back( - type::ValueFactory::GetVarcharValue(c_last).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_index_scan_desc( - customer_table_skey_index_oid, customer_key_column_ids, - customer_expr_types, customer_key_values, runtime_keys); - - auto predicate = nullptr; - planner::IndexScanPlan customer_index_scan_node(customer_table, predicate, - customer_column_ids, - customer_index_scan_desc); - - executor::IndexScanExecutor customer_index_scan_executor( - &customer_index_scan_node, context.get()); - - // Construct order by executor - std::vector sort_keys = {1}; - std::vector descend_flags = {false}; - std::vector output_columns = {0, 1, 2, 3, 4}; - - planner::OrderByPlan customer_order_by_node(sort_keys, descend_flags, - output_columns); - - executor::OrderByExecutor customer_order_by_executor( - &customer_order_by_node, context.get()); - - customer_order_by_executor.AddChild(&customer_index_scan_executor); - - auto result = ExecuteRead(&customer_order_by_executor); - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - - PELOTON_ASSERT(result.size() > 0); - // Get the middle one - size_t name_count = result.size(); - auto &customer = result[name_count / 2]; - PELOTON_ASSERT(customer.size() > 0); - c_id = type::ValuePeeker::PeekInteger(customer[0]); - } - - if (c_id < 0) { - LOG_ERROR("wrong c_id"); - PELOTON_ASSERT(false); - } - - LOG_TRACE( - "getLastOrder: SELECT O_ID, O_CARRIER_ID, O_ENTRY_D FROM ORDERS WHERE " - "O_W_ID = ? AND O_D_ID = ? AND O_C_ID = ? ORDER BY O_ID DESC LIMIT 1, # " - "w_id, d_id, c_id"); - - // Construct index scan executor - std::vector orders_column_ids = {COL_IDX_O_ID, COL_IDX_O_CARRIER_ID, - COL_IDX_O_ENTRY_D}; - std::vector orders_key_column_ids = {COL_IDX_O_W_ID, COL_IDX_O_D_ID, - COL_IDX_O_C_ID}; - std::vector orders_expr_types; - std::vector orders_key_values; - std::vector runtime_keys; - - orders_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - orders_key_values.push_back(type::ValueFactory::GetIntegerValue(w_id).Copy()); - orders_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - orders_key_values.push_back(type::ValueFactory::GetIntegerValue(d_id).Copy()); - orders_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - orders_key_values.push_back(type::ValueFactory::GetIntegerValue(c_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc orders_index_scan_desc( - orders_table_skey_index_oid, orders_key_column_ids, orders_expr_types, - orders_key_values, runtime_keys); - - auto predicate = nullptr; - - planner::IndexScanPlan orders_index_scan_node( - orders_table, predicate, orders_column_ids, orders_index_scan_desc); - - executor::IndexScanExecutor orders_index_scan_executor( - &orders_index_scan_node, context.get()); - - // Construct order by executor - std::vector sort_keys = {0}; - std::vector descend_flags = {true}; - std::vector output_columns = {0, 1, 2}; - - planner::OrderByPlan orders_order_by_node(sort_keys, descend_flags, - output_columns); - - executor::OrderByExecutor orders_order_by_executor(&orders_order_by_node, - context.get()); - orders_order_by_executor.AddChild(&orders_index_scan_executor); - - // Construct limit executor - size_t limit = 1; - size_t offset = 0; - planner::LimitPlan limit_node(limit, offset); - executor::LimitExecutor limit_executor(&limit_node, context.get()); - limit_executor.AddChild(&orders_order_by_executor); - - auto orders = ExecuteRead(&orders_order_by_executor); - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - - if (orders.size() != 0) { - LOG_TRACE( - "getOrderLines: SELECT OL_SUPPLY_W_ID, OL_I_ID, OL_QUANTITY, " - "OL_AMOUNT, OL_DELIVERY_D FROM ORDER_LINE WHERE OL_W_ID = ? AND " - "OL_D_ID = ? AND OL_O_ID = ?, # w_id, d_id, o_id"); - - // Construct index scan executor - std::vector order_line_column_ids = { - COL_IDX_OL_SUPPLY_W_ID, COL_IDX_OL_I_ID, COL_IDX_OL_QUANTITY, - COL_IDX_OL_AMOUNT, COL_IDX_OL_DELIVERY_D}; - std::vector order_line_key_column_ids = { - COL_IDX_OL_W_ID, COL_IDX_OL_D_ID, COL_IDX_OL_O_ID}; - std::vector order_line_expr_types; - std::vector order_line_key_values; - - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(w_id).Copy()); - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_key_values.push_back(orders[0][0]); - - planner::IndexScanPlan::IndexScanDesc order_line_index_scan_desc( - order_line_table_skey_index_oid, order_line_key_column_ids, - order_line_expr_types, order_line_key_values, runtime_keys); - - predicate = nullptr; - - planner::IndexScanPlan order_line_index_scan_node( - order_line_table, predicate, order_line_column_ids, - order_line_index_scan_desc); - - executor::IndexScanExecutor order_line_index_scan_executor( - &order_line_index_scan_node, context.get()); - - ExecuteRead(&order_line_index_scan_executor); - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - } - - PELOTON_ASSERT(txn->GetResult() == ResultType::SUCCESS); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - return true; - } else { - return false; - } -} -} -} -} diff --git a/src/main/tpcc/tpcc_payment.cpp b/src/main/tpcc/tpcc_payment.cpp deleted file mode 100644 index 79a586bc5e8..00000000000 --- a/src/main/tpcc/tpcc_payment.cpp +++ /dev/null @@ -1,743 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_payment.cpp -// -// Identification: src/main/tpcc/tpcc_payment.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_workload.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/generator.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/timer.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/executor_context.h" -#include "executor/index_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/update_executor.h" - -#include "common/container_tuple.h" -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/tuple_value_expression.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/materialization_plan.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -bool RunPayment(const size_t &thread_id) { - /* - "PAYMENT": { - "getWarehouse": "SELECT W_NAME, W_STREET_1, W_STREET_2, W_CITY, W_STATE, - W_ZIP FROM WAREHOUSE WHERE W_ID = ?", # w_id - "updateWarehouseBalance": "UPDATE WAREHOUSE SET W_YTD = W_YTD + ? WHERE - W_ID = ?", # h_amount, w_id - "getDistrict": "SELECT D_NAME, D_STREET_1, D_STREET_2, D_CITY, D_STATE, - D_ZIP FROM DISTRICT WHERE D_W_ID = ? AND D_ID = ?", # w_id, d_id - "updateDistrictBalance": "UPDATE DISTRICT SET D_YTD = D_YTD + ? WHERE - D_W_ID = ? AND D_ID = ?", # h_amount, d_w_id, d_id - "getCustomerByCustomerId": "SELECT C_ID, C_FIRST, C_MIDDLE, C_LAST, - C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, C_PHONE, C_SINCE, C_CREDIT, - C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_DATA - FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ?", # w_id, d_id, - c_id - "getCustomersByLastName": "SELECT C_ID, C_FIRST, C_MIDDLE, C_LAST, - C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, C_PHONE, C_SINCE, C_CREDIT, - C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_DATA - FROM CUSTOMER WHERE C_W_ID = ? AND C_D_ID = ? AND C_LAST = ? ORDER BY - C_FIRST", # w_id, d_id, c_last - "updateBCCustomer": "UPDATE CUSTOMER SET C_BALANCE = ?, C_YTD_PAYMENT = ?, - C_PAYMENT_CNT = ?, C_DATA = ? WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = - ?", # c_balance, c_ytd_payment, c_payment_cnt, c_data, c_w_id, c_d_id, c_id - "updateGCCustomer": "UPDATE CUSTOMER SET C_BALANCE = ?, C_YTD_PAYMENT = ?, - C_PAYMENT_CNT = ? WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ?", # - c_balance, c_ytd_payment, c_payment_cnt, c_w_id, c_d_id, c_id - "insertHistory": "INSERT INTO HISTORY VALUES (?, ?, ?, ?, ?, ?, ?, ?)", - } - */ - - LOG_TRACE("-------------------------------------"); - - ///////////////////////////////////////////////////////// - // PREPARE ARGUMENTS - ///////////////////////////////////////////////////////// - int warehouse_id = GenerateWarehouseId(thread_id); - int district_id = GetRandomInteger(0, state.districts_per_warehouse - 1); - int customer_warehouse_id; - int customer_district_id; - int customer_id = -1; - std::string customer_lastname; - double h_amount = - GetRandomFixedPoint(2, payment_min_amount, payment_max_amount); - // WARN: Hard code the date as 0. may cause problem - int h_date = 0; - - int x = GetRandomInteger(1, 100); - // currently we only retrieve data by id. - int y = 100; // GetRandomInteger(1, 100); - - // 85%: paying through own warehouse ( or there is only 1 warehosue) - if (state.warehouse_count == 1 || x <= 85) { - customer_warehouse_id = warehouse_id; - customer_district_id = district_id; - } - // 15%: paying through another warehouse - else { - customer_warehouse_id = - GetRandomIntegerExcluding(0, state.warehouse_count - 1, warehouse_id); - PELOTON_ASSERT(customer_warehouse_id != warehouse_id); - customer_district_id = - GetRandomInteger(0, state.districts_per_warehouse - 1); - } - - // 60%: payment by last name - if (y <= 60) { - LOG_TRACE("By last name"); - customer_lastname = GetRandomLastName(state.customers_per_district); - } - // 40%: payment by id - else { - LOG_TRACE("By id"); - customer_id = GetRandomInteger(0, state.customers_per_district - 1); - } - - std::vector runtime_keys; - - ///////////////////////////////////////////////////////// - // BEGIN TRANSACTION - ///////////////////////////////////////////////////////// - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - auto txn = txn_manager.BeginTransaction(thread_id); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - std::vector customer; - - if (customer_id >= 0) { - LOG_TRACE( - "getCustomerByCustomerId: WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = " - "? , # w_id = %d, d_id = %d, c_id = %d", - warehouse_id, district_id, customer_id); - - std::vector customer_column_ids = { - 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20}; - - std::vector customer_pkey_column_ids = {0, 1, 2}; - std::vector customer_pexpr_types; - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector customer_pkey_values; - - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_id).Copy()); - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_pindex_scan_desc( - customer_table_pkey_index_oid, customer_pkey_column_ids, - customer_pexpr_types, customer_pkey_values, runtime_keys); - - planner::IndexScanPlan customer_pindex_scan_node(customer_table, nullptr, - customer_column_ids, - customer_pindex_scan_desc); - - executor::IndexScanExecutor customer_pindex_scan_executor( - &customer_pindex_scan_node, context.get()); - - auto customer_list = ExecuteRead(&customer_pindex_scan_executor); - - // Check if aborted - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (customer_list.size() != 1) { - PELOTON_ASSERT(false); - } - - customer = customer_list[0]; - - } else { - PELOTON_ASSERT(customer_lastname.empty() == false); - - LOG_TRACE( - "getCustomersByLastName: WHERE C_W_ID = ? AND C_D_ID = ? AND C_LAST = " - "? ORDER BY C_FIRST, # w_id = %d, d_id = %d, c_last = %s", - warehouse_id, district_id, customer_lastname.c_str()); - - std::vector customer_column_ids = { - 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20}; - - std::vector customer_key_column_ids = {1, 2, 5}; - std::vector customer_expr_types; - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector customer_key_values; - - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - customer_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - customer_key_values.push_back( - type::ValueFactory::GetVarcharValue(customer_lastname).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_index_scan_desc( - customer_table_skey_index_oid, customer_key_column_ids, - customer_expr_types, customer_key_values, runtime_keys); - - planner::IndexScanPlan customer_index_scan_node( - customer_table, nullptr, customer_column_ids, customer_index_scan_desc); - - executor::IndexScanExecutor customer_index_scan_executor( - &customer_index_scan_node, context.get()); - - auto customer_list = ExecuteRead(&customer_index_scan_executor); - - // Check if aborted - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (customer_list.size() < 1) { - LOG_INFO("C_W_ID=%d, C_D_ID=%d", warehouse_id, district_id); - PELOTON_ASSERT(false); - } - - // Get the midpoint customer's id - auto mid_pos = (customer_list.size() - 1) / 2; - customer = customer_list[mid_pos]; - } - - LOG_TRACE("getWarehouse:WHERE W_ID = ? # w_id = %d", warehouse_id); - - std::vector warehouse_key_column_ids = {0}; - std::vector warehouse_expr_types; - warehouse_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector warehouse_key_values; - - warehouse_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc warehouse_index_scan_desc( - warehouse_table_pkey_index_oid, warehouse_key_column_ids, - warehouse_expr_types, warehouse_key_values, runtime_keys); - - std::vector warehouse_column_ids = {1, 2, 3, 4, 5, 6, 8}; - - planner::IndexScanPlan warehouse_index_scan_node(warehouse_table, nullptr, - warehouse_column_ids, - warehouse_index_scan_desc); - - executor::IndexScanExecutor warehouse_index_scan_executor( - &warehouse_index_scan_node, context.get()); - - // Execute the query - auto warehouse_list = ExecuteRead(&warehouse_index_scan_executor); - - // Check if aborted - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (warehouse_list.size() != 1) { - PELOTON_ASSERT(false); - } - - LOG_TRACE( - "getDistrict: WHERE D_W_ID = ? AND D_ID = ?, # w_id = %d, d_id = %d", - warehouse_id, district_id); - // We also retrieve the original D_YTD from this query, - // which is not the standard TPCC approach - - std::vector district_key_column_ids = {0, 1}; - std::vector district_expr_types; - district_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - district_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector district_key_values; - - district_key_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - district_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc district_index_scan_desc( - district_table_pkey_index_oid, district_key_column_ids, - district_expr_types, district_key_values, runtime_keys); - - std::vector district_column_ids = {2, 3, 4, 5, 6, 7, 9}; - - planner::IndexScanPlan district_index_scan_node( - district_table, nullptr, district_column_ids, district_index_scan_desc); - - executor::IndexScanExecutor district_index_scan_executor( - &district_index_scan_node, context.get()); - - // Execute the query - auto district_list = ExecuteRead(&district_index_scan_executor); - - // Check if aborted - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (district_list.size() != 1) { - PELOTON_ASSERT(false); - } - - double warehouse_new_balance = - type::ValuePeeker::PeekDouble(warehouse_list[0][6]) + h_amount; - - LOG_TRACE( - "updateWarehouseBalance: UPDATE WAREHOUSE SET W_YTD = W_YTD + ? WHERE " - "W_ID = ?,# h_amount = %f, w_id = %d", - h_amount, warehouse_id); - - std::vector warehouse_update_column_ids = {8}; - - std::vector warehouse_update_key_values; - - warehouse_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc warehouse_update_index_scan_desc( - warehouse_table_pkey_index_oid, warehouse_key_column_ids, - warehouse_expr_types, warehouse_update_key_values, runtime_keys); - - planner::IndexScanPlan warehouse_update_index_scan_node( - warehouse_table, nullptr, warehouse_update_column_ids, - warehouse_update_index_scan_desc); - - executor::IndexScanExecutor warehouse_update_index_scan_executor( - &warehouse_update_index_scan_node, context.get()); - - TargetList warehouse_target_list; - DirectMapList warehouse_direct_map_list; - - // Keep the first 8 columns unchanged - for (oid_t col_itr = 0; col_itr < 8; ++col_itr) { - warehouse_direct_map_list.emplace_back(col_itr, - std::pair(0, col_itr)); - } - // Update the 9th column - type::Value warehouse_new_balance_value = - type::ValueFactory::GetDecimalValue(warehouse_new_balance).Copy(); - - planner::DerivedAttribute warehouse_bal{ - expression::ExpressionUtil::ConstantValueFactory( - warehouse_new_balance_value)}; - warehouse_target_list.emplace_back(8, warehouse_bal); - - std::unique_ptr warehouse_project_info( - new planner::ProjectInfo(std::move(warehouse_target_list), - std::move(warehouse_direct_map_list))); - planner::UpdatePlan warehouse_update_node(warehouse_table, - std::move(warehouse_project_info)); - - executor::UpdateExecutor warehouse_update_executor(&warehouse_update_node, - context.get()); - - warehouse_update_executor.AddChild(&warehouse_update_index_scan_executor); - - // Execute the query - ExecuteUpdate(&warehouse_update_executor); - - // Check if aborted - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - double district_new_balance = - type::ValuePeeker::PeekDouble(district_list[0][6]) + h_amount; - - LOG_TRACE( - "updateDistrictBalance: UPDATE DISTRICT SET D_YTD = D_YTD + ? WHERE " - "D_W_ID = ? AND D_ID = ?,# h_amount = %f, d_w_id = %d, d_id = %d", - h_amount, district_id, warehouse_id); - - std::vector district_update_column_ids = {9}; - - std::vector district_update_key_values; - - district_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(district_id).Copy()); - district_update_key_values.push_back( - type::ValueFactory::GetIntegerValue(warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc district_update_index_scan_desc( - district_table_pkey_index_oid, district_key_column_ids, - district_expr_types, district_update_key_values, runtime_keys); - - planner::IndexScanPlan district_update_index_scan_node( - district_table, nullptr, district_update_column_ids, - district_update_index_scan_desc); - - executor::IndexScanExecutor district_update_index_scan_executor( - &district_update_index_scan_node, context.get()); - - TargetList district_target_list; - DirectMapList district_direct_map_list; - - // Keep all columns unchanged except for the - for (oid_t col_itr = 0; col_itr < 11; ++col_itr) { - if (col_itr != 9) { - district_direct_map_list.emplace_back( - col_itr, std::pair(0, col_itr)); - } - } - // Update the 10th column - type::Value district_new_balance_value = - type::ValueFactory::GetDecimalValue(district_new_balance).Copy(); - - planner::DerivedAttribute district_bal{ - expression::ExpressionUtil::ConstantValueFactory( - district_new_balance_value)}; - district_target_list.emplace_back(9, district_bal); - - std::unique_ptr district_project_info( - new planner::ProjectInfo(std::move(district_target_list), - std::move(district_direct_map_list))); - planner::UpdatePlan district_update_node(district_table, - std::move(district_project_info)); - - executor::UpdateExecutor district_update_executor(&district_update_node, - context.get()); - - district_update_executor.AddChild(&district_update_index_scan_executor); - - // Execute the query - ExecuteUpdate(&district_update_executor); - - // Check the result - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - std::string customer_credit = type::ValuePeeker::PeekVarchar(customer[11]); - - double customer_balance = - type::ValuePeeker::PeekDouble(customer[14]) - h_amount; - double customer_ytd_payment = - type::ValuePeeker::PeekDouble(customer[15]) + h_amount; - int customer_payment_cnt = type::ValuePeeker::PeekInteger(customer[16]) + 1; - - customer_id = type::ValuePeeker::PeekInteger(customer[0]); - - // NOTE: Workaround, we assign a constant to the customer's data field - - // Check the credit record of the user - if (customer_credit == customers_bad_credit) { - LOG_TRACE( - "updateBCCustomer:# c_balance = %f, c_ytd_payment = %f, c_payment_cnt " - "= %d, c_data = %s, c_w_id = %d, c_d_id = %d, c_id = %d", - customer_balance, customer_ytd_payment, customer_payment_cnt, - data_constant.c_str(), customer_warehouse_id, customer_district_id, - customer_id); - - std::vector customer_pkey_column_ids = {0, 1, 2}; - std::vector customer_pexpr_types; - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector customer_pkey_values; - - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_id).Copy()); - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_district_id).Copy()); - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_pindex_scan_desc( - customer_table_pkey_index_oid, customer_pkey_column_ids, - customer_pexpr_types, customer_pkey_values, runtime_keys); - - std::vector customer_update_bc_column_ids = {16, 17, 18, 20}; - - // Create update executor - planner::IndexScanPlan customer_update_bc_index_scan_node( - customer_table, nullptr, customer_update_bc_column_ids, - customer_pindex_scan_desc); - - executor::IndexScanExecutor customer_update_bc_index_scan_executor( - &customer_update_bc_index_scan_node, context.get()); - - TargetList customer_bc_target_list; - DirectMapList customer_bc_direct_map_list; - - // Only update the 17th to 19th and the 21th columns - for (oid_t col_itr = 0; col_itr < 21; ++col_itr) { - if ((col_itr >= 16 && col_itr <= 18) || (col_itr == 20)) { - continue; - } - customer_bc_direct_map_list.emplace_back( - col_itr, std::pair(0, col_itr)); - } - - type::Value customer_new_balance_value = - type::ValueFactory::GetDecimalValue(customer_balance).Copy(); - type::Value customer_new_ytd_value = - type::ValueFactory::GetDecimalValue(customer_ytd_payment).Copy(); - type::Value customer_new_paycnt_value = - type::ValueFactory::GetIntegerValue(customer_payment_cnt).Copy(); - type::Value customer_new_data_value = - type::ValueFactory::GetVarcharValue(data_constant.c_str()).Copy(); - - planner::DerivedAttribute c_new_bal{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_balance_value)}; - planner::DerivedAttribute c_new_ytd{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_ytd_value)}; - planner::DerivedAttribute c_new_paycnt{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_paycnt_value)}; - planner::DerivedAttribute c_new_data{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_data_value)}; - - customer_bc_target_list.emplace_back(16, c_new_bal); - customer_bc_target_list.emplace_back(17, c_new_ytd); - customer_bc_target_list.emplace_back(18, c_new_paycnt); - customer_bc_target_list.emplace_back(20, c_new_data); - - std::unique_ptr customer_bc_project_info( - new planner::ProjectInfo(std::move(customer_bc_target_list), - std::move(customer_bc_direct_map_list))); - - planner::UpdatePlan customer_update_bc_node( - customer_table, std::move(customer_bc_project_info)); - - executor::UpdateExecutor customer_update_bc_executor( - &customer_update_bc_node, context.get()); - - customer_update_bc_executor.AddChild( - &customer_update_bc_index_scan_executor); - - // Execute the query - ExecuteUpdate(&customer_update_bc_executor); - } else { - LOG_TRACE( - "updateGCCustomer: # c_balance = %f, c_ytd_payment = %f, c_payment_cnt " - "= %d, c_w_id = %d, c_d_id = %d, c_id = %d", - customer_balance, customer_ytd_payment, customer_payment_cnt, - customer_warehouse_id, customer_district_id, customer_id); - - std::vector customer_pkey_column_ids = {0, 1, 2}; - std::vector customer_pexpr_types; - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - customer_pexpr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector customer_pkey_values; - - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_id).Copy()); - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_district_id).Copy()); - customer_pkey_values.push_back( - type::ValueFactory::GetIntegerValue(customer_warehouse_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc customer_pindex_scan_desc( - customer_table_pkey_index_oid, customer_pkey_column_ids, - customer_pexpr_types, customer_pkey_values, runtime_keys); - - std::vector customer_update_gc_column_ids = {16, 17, 18}; - - // Create update executor - planner::IndexScanPlan customer_update_gc_index_scan_node( - customer_table, nullptr, customer_update_gc_column_ids, - customer_pindex_scan_desc); - - executor::IndexScanExecutor customer_update_gc_index_scan_executor( - &customer_update_gc_index_scan_node, context.get()); - - TargetList customer_gc_target_list; - DirectMapList customer_gc_direct_map_list; - - // Only update the 17th to 19th columns - for (oid_t col_itr = 0; col_itr < 21; ++col_itr) { - if (col_itr >= 16 && col_itr <= 18) { - continue; - } - customer_gc_direct_map_list.emplace_back( - col_itr, std::pair(0, col_itr)); - } - type::Value customer_new_balance_value = - type::ValueFactory::GetDecimalValue(customer_balance).Copy(); - type::Value customer_new_ytd_value = - type::ValueFactory::GetDecimalValue(customer_ytd_payment).Copy(); - type::Value customer_new_paycnt_value = - type::ValueFactory::GetIntegerValue(customer_payment_cnt).Copy(); - - planner::DerivedAttribute c_new_bal{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_balance_value)}; - planner::DerivedAttribute c_new_ytd{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_ytd_value)}; - planner::DerivedAttribute c_new_paycnt{ - expression::ExpressionUtil::ConstantValueFactory( - customer_new_paycnt_value)}; - - customer_gc_target_list.emplace_back(16, c_new_bal); - customer_gc_target_list.emplace_back(17, c_new_ytd); - customer_gc_target_list.emplace_back(18, c_new_paycnt); - - std::unique_ptr customer_gc_project_info( - new planner::ProjectInfo(std::move(customer_gc_target_list), - std::move(customer_gc_direct_map_list))); - - planner::UpdatePlan customer_update_gc_node( - customer_table, std::move(customer_gc_project_info)); - - executor::UpdateExecutor customer_update_gc_executor( - &customer_update_gc_node, context.get()); - - customer_update_gc_executor.AddChild( - &customer_update_gc_index_scan_executor); - - // Execute the query - ExecuteUpdate(&customer_update_gc_executor); - } - - // Check the result - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - LOG_TRACE( - "insertHistory: INSERT INTO HISTORY VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - std::unique_ptr history_tuple( - new storage::Tuple(history_table->GetSchema(), true)); - - // H_C_ID - history_tuple->SetValue(0, type::ValueFactory::GetIntegerValue(customer_id), - nullptr); - // H_C_D_ID - history_tuple->SetValue( - 1, type::ValueFactory::GetIntegerValue(customer_district_id), nullptr); - // H_C_W_ID - history_tuple->SetValue( - 2, type::ValueFactory::GetIntegerValue(customer_warehouse_id), nullptr); - // H_D_ID - history_tuple->SetValue(3, type::ValueFactory::GetIntegerValue(district_id), - nullptr); - // H_W_ID - history_tuple->SetValue(4, type::ValueFactory::GetIntegerValue(warehouse_id), - nullptr); - // H_DATE - history_tuple->SetValue(5, type::ValueFactory::GetTimestampValue(h_date), - nullptr); - // H_AMOUNT - history_tuple->SetValue(6, type::ValueFactory::GetDecimalValue(h_amount), - nullptr); - // H_DATA - // Note: workaround - history_tuple->SetValue(7, type::ValueFactory::GetVarcharValue(data_constant), - context.get()->GetPool()); - - planner::InsertPlan history_insert_node(history_table, - std::move(history_tuple)); - executor::InsertExecutor history_insert_executor(&history_insert_node, - context.get()); - - // Execute - history_insert_executor.Execute(); - - // Check result - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - PELOTON_ASSERT(txn->GetResult() == ResultType::SUCCESS); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - return true; - } else { - PELOTON_ASSERT(result == ResultType::ABORTED || - result == ResultType::FAILURE); - return false; - } -} -} -} -} diff --git a/src/main/tpcc/tpcc_stock_level.cpp b/src/main/tpcc/tpcc_stock_level.cpp deleted file mode 100644 index 1cad0da3dd2..00000000000 --- a/src/main/tpcc/tpcc_stock_level.cpp +++ /dev/null @@ -1,273 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_stock_level.cpp -// -// Identification: src/main/tpcc/tpcc_stock_level.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" -#include "benchmark/tpcc/tpcc_workload.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/generator.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/timer.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/aggregate_executor.h" -#include "executor/executor_context.h" -#include "executor/index_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/nested_loop_join_executor.h" -#include "executor/update_executor.h" - -#include "common/container_tuple.h" -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/tuple_value_expression.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/aggregate_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/materialization_plan.h" -#include "planner/nested_loop_join_plan.h" -#include "planner/project_info.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -bool RunStockLevel(const size_t &thread_id) { - /* - "STOCK_LEVEL": { - "getOId": "SELECT D_NEXT_O_ID FROM DISTRICT WHERE D_W_ID = ? AND D_ID = ?", - "getStockCount": "SELECT COUNT(DISTINCT(OL_I_ID)) FROM ORDER_LINE, STOCK - WHERE OL_W_ID = ? AND OL_D_ID = ? AND OL_O_ID < ? AND OL_O_ID >= ? AND - S_W_ID = ? AND S_I_ID = OL_I_ID AND S_QUANTITY < ? - } - */ - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto txn = txn_manager.BeginTransaction(thread_id); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - // Prepare random data - int w_id = GenerateWarehouseId(thread_id); - int d_id = GetRandomInteger(0, state.districts_per_warehouse - 1); - int threshold = GetRandomInteger(stock_min_threshold, stock_max_threshold); - - LOG_TRACE( - "getOId: SELECT D_NEXT_O_ID FROM DISTRICT WHERE D_W_ID = ? AND D_ID = ?"); - - // Construct index scan executor - std::vector district_column_ids = {COL_IDX_D_NEXT_O_ID}; - std::vector district_key_column_ids = {COL_IDX_D_W_ID, COL_IDX_D_ID}; - std::vector district_expr_types; - std::vector district_key_values; - std::vector runtime_keys; - - district_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - district_key_values.push_back( - type::ValueFactory::GetIntegerValue(w_id).Copy()); - district_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - district_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc district_index_scan_desc( - district_table_pkey_index_oid, district_key_column_ids, - district_expr_types, district_key_values, runtime_keys); - - expression::AbstractExpression *predicate = nullptr; - planner::IndexScanPlan district_index_scan_node( - district_table, predicate, district_column_ids, district_index_scan_desc); - executor::IndexScanExecutor district_index_scan_executor( - &district_index_scan_node, context.get()); - - auto districts = ExecuteRead(&district_index_scan_executor); - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - if (districts.size() != 1) { - LOG_ERROR("incorrect districts size : %lu", districts.size()); - PELOTON_ASSERT(false); - } - - type::Value o_id = districts[0][0]; - - LOG_TRACE( - "getStockCount: SELECT COUNT(DISTINCT(OL_I_ID)) FROM ORDER_LINE, STOCK " - "WHERE OL_W_ID = ? AND OL_D_ID = ? AND OL_O_ID < ? AND OL_O_ID >= ? AND " - "S_W_ID = ? AND S_I_ID = OL_I_ID AND S_QUANTITY < ?"); - - int max_o_id = type::ValuePeeker::PeekInteger(o_id); - int min_o_id = max_o_id - 20; - - ////////////////////////////////////////////////////////////// - std::vector order_line_column_ids = {COL_IDX_OL_I_ID}; - std::vector order_line_key_column_ids = { - COL_IDX_OL_W_ID, COL_IDX_OL_D_ID, COL_IDX_OL_O_ID}; - std::vector order_line_expr_types; - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - order_line_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - auto order_line_skey_index = - order_line_table->GetIndexWithOid(order_line_table_skey_index_oid); - - ////////////////////////////////////////////////////////////// - std::vector stock_column_ids = {COL_IDX_S_QUANTITY}; - std::vector stock_key_column_ids = {COL_IDX_S_W_ID, COL_IDX_S_I_ID}; - std::vector stock_expr_types; - stock_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - stock_expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - auto stock_pkey_index = - stock_table->GetIndexWithOid(stock_table_pkey_index_oid); - - ////////////////////////////////////////////////////////////// - std::unordered_set distinct_items; - - for (int curr_o_id = min_o_id; curr_o_id < max_o_id; ++curr_o_id) { - //////////////////////////////////////////////////////////////// - /////////// Construct left table index scan //////////////////// - //////////////////////////////////////////////////////////////// - - std::vector order_line_key_values; - - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(w_id).Copy()); - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(d_id).Copy()); - order_line_key_values.push_back( - type::ValueFactory::GetIntegerValue(curr_o_id).Copy()); - - planner::IndexScanPlan::IndexScanDesc order_line_index_scan_desc( - order_line_table_skey_index_oid, order_line_key_column_ids, - order_line_expr_types, order_line_key_values, runtime_keys); - - planner::IndexScanPlan order_line_index_scan_node( - order_line_table, nullptr, order_line_column_ids, - order_line_index_scan_desc); - - executor::IndexScanExecutor order_line_index_scan_executor( - &order_line_index_scan_node, context.get()); - - auto order_line_values = ExecuteRead(&order_line_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (order_line_values.size() == 0) { - LOG_TRACE("order line return size incorrect : %lu", - order_line_values.size()); - continue; - } - - auto item_id = order_line_values[0][0]; - - LOG_TRACE("item_id: %s", item_id.GetInfo().c_str()); - - ////////////////////////////////////////////////////////////////// - ///////////// Construct right table index scan /////////////////// - ////////////////////////////////////////////////////////////////// - - std::vector stock_key_values; - - stock_key_values.push_back( - type::ValueFactory::GetIntegerValue(w_id).Copy()); - stock_key_values.push_back(item_id); - - planner::IndexScanPlan::IndexScanDesc stock_index_scan_desc( - stock_table_pkey_index_oid, stock_key_column_ids, stock_expr_types, - stock_key_values, runtime_keys); - - // Add predicate S_QUANTITY < threshold - planner::IndexScanPlan stock_index_scan_node( - stock_table, nullptr, stock_column_ids, stock_index_scan_desc); - - executor::IndexScanExecutor stock_index_scan_executor( - &stock_index_scan_node, context.get()); - - auto stock_values = ExecuteRead(&stock_index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - LOG_TRACE("abort transaction"); - txn_manager.AbortTransaction(txn); - return false; - } - - if (stock_values.size() == 0) { - // LOG_ERROR("stock return size incorrect : %lu", - // order_line_values.size()); - continue; - } - - auto quantity = stock_values[0][0]; - if (type::ValuePeeker::PeekInteger(quantity) < threshold) { - distinct_items.insert(type::ValuePeeker::PeekInteger(item_id)); - } - } - LOG_TRACE("number of distinct items=%lu", distinct_items.size()); - - PELOTON_ASSERT(txn->GetResult() == ResultType::SUCCESS); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - return true; - } else { - return false; - } - - return true; -} -} -} -} diff --git a/src/main/tpcc/tpcc_workload.cpp b/src/main/tpcc/tpcc_workload.cpp deleted file mode 100644 index 3e1705b4b42..00000000000 --- a/src/main/tpcc/tpcc_workload.cpp +++ /dev/null @@ -1,421 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpcc_workload.cpp -// -// Identification: src/main/tpcc/tpcc_workload.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "storage/storage_manager.h" - -#include "benchmark/benchmark_common.h" -#include "benchmark/tpcc/tpcc_workload.h" -#include "benchmark/tpcc/tpcc_configuration.h" -#include "benchmark/tpcc/tpcc_loader.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/internal_types.h" -#include "type/value.h" -#include "type/value_factory.h" -#include "common/logger.h" -#include "common/timer.h" -#include "common/generator.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" -#include "concurrency/epoch_manager_factory.h" - -#include "executor/executor_context.h" -#include "executor/abstract_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/update_executor.h" -#include "executor/index_scan_executor.h" - -#include "expression/abstract_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/tuple_value_expression.h" -#include "expression/comparison_expression.h" -#include "expression/expression_util.h" -#include "common/container_tuple.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/materialization_plan.h" -#include "planner/insert_plan.h" -#include "planner/update_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/nested_loop_join_plan.h" -#include "planner/aggregate_plan.h" -#include "planner/order_by_plan.h" -#include "planner/limit_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" -#include "storage/storage_manager.h" - -namespace peloton { -namespace benchmark { -namespace tpcc { - -///////////////////////////////////////////////////////// -// WORKLOAD -///////////////////////////////////////////////////////// - -#define STOCK_LEVEL_RATIO 0.04 -#define ORDER_STATUS_RATIO 0.0 -#define PAYMENT_RATIO 0.48 -#define NEW_ORDER_RATIO 0.48 - -volatile bool is_running = true; - -PadInt *abort_counts; -PadInt *commit_counts; - -size_t GenerateWarehouseId(const size_t &thread_id) { - if (state.affinity) { - if (state.warehouse_count <= state.backend_count) { - return thread_id % state.warehouse_count; - } else { - int warehouse_per_partition = state.warehouse_count / state.backend_count; - int start_warehouse = warehouse_per_partition * thread_id; - int end_warehouse = ((int)thread_id != (state.backend_count - 1)) ? - start_warehouse + warehouse_per_partition - 1 : state.warehouse_count - 1; - return GetRandomInteger(start_warehouse, end_warehouse); - } - } else { - return GetRandomInteger(0, state.warehouse_count - 1); - } -} - -#ifndef __APPLE__ -void PinToCore(size_t core) { - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(core, &cpuset); - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); -#else -void PinToCore(size_t UNUSED_ATTRIBUTE core) { -// Mac OS X does not export interfaces that identify processors or control thread placement -// explicit thread to processor binding is not supported. -// Reference: https://superuser.com/questions/149312/how-to-set-processor-affinity-on-os-x -#endif -} - -void RunBackend(const size_t thread_id) { - - PinToCore(thread_id); - - if (concurrency::EpochManagerFactory::GetEpochType() == EpochType::DECENTRALIZED_EPOCH) { - // register thread to epoch manager - auto &epoch_manager = concurrency::EpochManagerFactory::GetInstance(); - epoch_manager.RegisterThread(thread_id); - } - - PadInt &execution_count_ref = abort_counts[thread_id]; - PadInt &transaction_count_ref = commit_counts[thread_id]; - - // backoff - uint32_t backoff_shifts = 0; - - while (true) { - - if (is_running == false) { - break; - } - - FastRandom rng(rand()); - - auto rng_val = rng.NextUniform(); - if (rng_val <= STOCK_LEVEL_RATIO) { - while (RunStockLevel(thread_id) == false) { - if (is_running == false) { - break; - } - execution_count_ref.data++; - // backoff - if (state.exp_backoff) { - if (backoff_shifts < 13) { - ++backoff_shifts; - } - uint64_t sleep_duration = 1UL << backoff_shifts; - sleep_duration *= 100; - std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); - } - } - } else if (rng_val <= ORDER_STATUS_RATIO + STOCK_LEVEL_RATIO) { - while (RunOrderStatus(thread_id) == false) { - if (is_running == false) { - break; - } - execution_count_ref.data++; - // backoff - if (state.exp_backoff) { - if (backoff_shifts < 13) { - ++backoff_shifts; - } - uint64_t sleep_duration = 1UL << backoff_shifts; - sleep_duration *= 100; - std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); - } - } - } else if (rng_val <= PAYMENT_RATIO + ORDER_STATUS_RATIO + STOCK_LEVEL_RATIO) { - while (RunPayment(thread_id) == false) { - if (is_running == false) { - break; - } - execution_count_ref.data++; - // backoff - if (state.exp_backoff) { - if (backoff_shifts < 13) { - ++backoff_shifts; - } - uint64_t sleep_duration = 1UL << backoff_shifts; - sleep_duration *= 100; - std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); - } - } - } else if (rng_val <= PAYMENT_RATIO + ORDER_STATUS_RATIO + STOCK_LEVEL_RATIO + NEW_ORDER_RATIO) { - while (RunNewOrder(thread_id) == false) { - if (is_running == false) { - break; - } - execution_count_ref.data++; - // backoff - if (state.exp_backoff) { - if (backoff_shifts < 13) { - ++backoff_shifts; - } - uint64_t sleep_duration = 1UL << backoff_shifts; - sleep_duration *= 100; - std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); - } - } - } else { - while (RunDelivery(thread_id) == false) { - if (is_running == false) { - break; - } - execution_count_ref.data++; - // backoff - if (state.exp_backoff) { - if (backoff_shifts < 13) { - ++backoff_shifts; - } - uint64_t sleep_duration = 1UL << backoff_shifts; - sleep_duration *= 100; - std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); - } - } - } - - backoff_shifts >>= 1; - transaction_count_ref.data++; - - } -} - -void RunWorkload() { - - // Execute the workload to build the log - std::vector thread_group; - size_t num_threads = state.backend_count; - - abort_counts = new PadInt[num_threads]; - PELOTON_MEMSET(abort_counts, 0, sizeof(PadInt) * num_threads); - - commit_counts = new PadInt[num_threads]; - PELOTON_MEMSET(commit_counts, 0, sizeof(PadInt) * num_threads); - - size_t profile_round = (size_t)(state.duration / state.profile_duration); - - PadInt **abort_counts_profiles = new PadInt *[profile_round]; - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - abort_counts_profiles[round_id] = new PadInt[num_threads]; - } - - PadInt **commit_counts_profiles = new PadInt *[profile_round]; - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - commit_counts_profiles[round_id] = new PadInt[num_threads]; - } - - for (size_t thread_itr = 0; thread_itr < num_threads; ++thread_itr) { - thread_group.push_back(std::thread(RunBackend, thread_itr)); - } - - ////////////////////////////////////// - oid_t last_tile_group_id = 0; - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - std::this_thread::sleep_for( - std::chrono::milliseconds(int(state.profile_duration * 1000))); - PELOTON_MEMCPY(abort_counts_profiles[round_id], abort_counts, - sizeof(PadInt) * num_threads); - PELOTON_MEMCPY(commit_counts_profiles[round_id], commit_counts, - sizeof(PadInt) * num_threads); - - storage::StorageManager *storage_manager = storage::StorageManager::GetInstance(); - oid_t current_tile_group_id = storage_manager->GetCurrentTileGroupId(); - if (round_id != 0) { - state.profile_memory.push_back(current_tile_group_id - last_tile_group_id); - } - last_tile_group_id = current_tile_group_id; - - } - - state.profile_memory.push_back(state.profile_memory.at(state.profile_memory.size() - 1)); - - is_running = false; - - // Join the threads with the main thread - for (size_t thread_itr = 0; thread_itr < num_threads; ++thread_itr) { - thread_group[thread_itr].join(); - } - - // calculate the throughput and abort rate for the first round. - uint64_t total_commit_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_commit_count += commit_counts_profiles[0][i].data; - } - - uint64_t total_abort_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_abort_count += abort_counts_profiles[0][i].data; - } - - state.profile_throughput - .push_back(total_commit_count * 1.0 / state.profile_duration); - state.profile_abort_rate - .push_back(total_abort_count * 1.0 / total_commit_count); - - // calculate the throughput and abort rate for the remaining rounds. - for (size_t round_id = 0; round_id < profile_round - 1; ++round_id) { - total_commit_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_commit_count += commit_counts_profiles[round_id + 1][i].data - - commit_counts_profiles[round_id][i].data; - } - - total_abort_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_abort_count += abort_counts_profiles[round_id + 1][i].data - - abort_counts_profiles[round_id][i].data; - } - - state.profile_throughput - .push_back(total_commit_count * 1.0 / state.profile_duration); - state.profile_abort_rate - .push_back(total_abort_count * 1.0 / total_commit_count); - } - - // calculate the aggregated throughput and abort rate. - total_commit_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_commit_count += commit_counts_profiles[profile_round - 1][i].data; - } - - total_abort_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_abort_count += abort_counts_profiles[profile_round - 1][i].data; - } - - state.throughput = total_commit_count * 1.0 / state.duration; - state.abort_rate = total_abort_count * 1.0 / total_commit_count; - - // cleanup everything. - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - delete[] abort_counts_profiles[round_id]; - abort_counts_profiles[round_id] = nullptr; - } - - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - delete[] commit_counts_profiles[round_id]; - commit_counts_profiles[round_id] = nullptr; - } - delete[] abort_counts_profiles; - abort_counts_profiles = nullptr; - delete[] commit_counts_profiles; - commit_counts_profiles = nullptr; - - delete[] abort_counts; - abort_counts = nullptr; - delete[] commit_counts; - commit_counts = nullptr; -} - -///////////////////////////////////////////////////////// -// HARNESS -///////////////////////////////////////////////////////// - -std::vector> ExecuteRead(executor::AbstractExecutor* executor) { - executor->Init(); - - std::vector> logical_tile_values; - - // Execute stuff - while (executor->Execute() == true) { - std::unique_ptr result_tile(executor->GetOutput()); - - if(result_tile == nullptr) { - break; - } - - auto column_count = result_tile->GetColumnCount(); - LOG_TRACE("result column count = %d\n", (int)column_count); - - for (oid_t tuple_id : *result_tile) { - ContainerTuple cur_tuple(result_tile.get(), - tuple_id); - std::vector tuple_values; - for (oid_t column_itr = 0; column_itr < column_count; column_itr++){ - auto value = cur_tuple.GetValue(column_itr); - tuple_values.push_back(value); - } - - // Move the tuple list - logical_tile_values.push_back(std::move(tuple_values)); - } - } - - return logical_tile_values; -} - -void ExecuteUpdate(executor::AbstractExecutor* executor) { - executor->Init(); - // Execute stuff - while (executor->Execute() == true); -} - - -void ExecuteDelete(executor::AbstractExecutor* executor) { - executor->Init(); - // Execute stuff - while (executor->Execute() == true); -} - - -} // namespace tpcc -} // namespace benchmark -} // namespace peloton diff --git a/src/main/tpch/tpch.cpp b/src/main/tpch/tpch.cpp deleted file mode 100644 index 001acb53f4c..00000000000 --- a/src/main/tpch/tpch.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch.cpp -// -// Identification: src/main/tpch/tpch.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include - -#include "benchmark/tpch/tpch_configuration.h" -#include "benchmark/tpch/tpch_database.h" -#include "benchmark/tpch/tpch_workload.h" -#include "common/logger.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -void Usage(FILE *out) { - fprintf(out, - "Command line options : tpch \n" - " -h --help : print help message \n" - " -i --input-dir : location of data \n" - " -n --num-runs : the number of runs to execute for each query \n" - " -s --suffix : input file suffix \n" - " -d --dict-encode : dictionary encode \n" - " -q --queries : comma-separated list of queries to run (i.g., 1,14 for Q1 and Q14) \n"); -} - -static struct option opts[] = { - {"input-dir", required_argument, NULL, 'i'}, - {"dict-encode", optional_argument, NULL, 'd'}, - {"queries", optional_argument, NULL, 'q'}, - {NULL, 0, NULL, 0}}; - -void ParseArguments(int argc, char **argv, Configuration &config) { - config.suffix = "tbl"; - - // Parse args - while (1) { - int idx = 0; - int c = getopt_long(argc, argv, "hi:n:s:dq:", opts, &idx); - - if (c == -1) break; - - switch (c) { - case 'i': { - char *input = optarg; - config.data_dir = input; - break; - } - case 'n': { - char *input = optarg; - config.num_runs = static_cast(std::atoi(input)); - } - case 'd': { - config.dictionary_encode = true; - break; - } - case 'q': { - char *csv_queries = optarg; - config.SetRunnableQueries(csv_queries); - break; - } - case 'h': { - Usage(stderr); - exit(EXIT_FAILURE); - } - default: { - LOG_ERROR("Unknown option: -%c-", c); - Usage(stderr); - exit(EXIT_FAILURE); - } - } - } - - // Validate everything - if (!config.IsValid()) { - exit(EXIT_FAILURE); - } - - LOG_INFO("Input directory : '%s'", config.data_dir.c_str()); - LOG_INFO("Dictionary encode : %s", - config.dictionary_encode ? "true" : "false"); - for (uint32_t i = 0; i < 22; i++) { - LOG_INFO("Run query %u : %s", i + 1, - config.queries_to_run[i] ? "true" : "false"); - } -} - -void RunBenchmark(const Configuration &config) { - // Create the DB instance - TPCHDatabase tpch_db{config}; - - // Create the benchmark - TPCHBenchmark tpch_benchmark{config, tpch_db}; - - // Run the benchmark - tpch_benchmark.RunBenchmark(); -} - -} // namespace tpch -} // namespace benchmark -} // namespace peloton - -// Entry point -int main(int argc, char **argv) { - // The configuration - peloton::benchmark::tpch::Configuration config; - - // Parse arguments - peloton::benchmark::tpch::ParseArguments(argc, argv, config); - - // Run workload - peloton::benchmark::tpch::RunBenchmark(config); - - return 0; -} \ No newline at end of file diff --git a/src/main/tpch/tpch_configuration.cpp b/src/main/tpch/tpch_configuration.cpp deleted file mode 100644 index f7ad9a70361..00000000000 --- a/src/main/tpch/tpch_configuration.cpp +++ /dev/null @@ -1,117 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_configuration.cpp -// -// Identification: src/main/tpch/tpch_configuration.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/tpch/tpch_configuration.h" - -#include - -#include "common/logger.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -oid_t kIntSize = - static_cast(type::Type::GetTypeSize(type::TypeId::INTEGER)); - -oid_t kDateSize = - static_cast(type::Type::GetTypeSize(type::TypeId::DATE)); - -oid_t kBigIntSize = - static_cast(type::Type::GetTypeSize(type::TypeId::BIGINT)); - -oid_t kDecimalSize = - static_cast(type::Type::GetTypeSize(type::TypeId::DECIMAL)); - -bool Configuration::IsValid() const { - struct stat info; - if (stat(data_dir.c_str(), &info) != 0) { - LOG_ERROR("Data directory [%s] isn't accessible", data_dir.c_str()); - return false; - } else if ((info.st_mode & S_IFDIR) == 0) { - LOG_ERROR("Data directory [%s] isn't a directory", data_dir.c_str()); - return false; - } - auto inputs = {GetCustomerPath(), GetLineitemPath(), - GetNationPath(), GetOrdersPath(), - GetPartSuppPath(), GetPartPath(), - GetSupplierPath(), GetRegionPath()}; - for (const auto &input : inputs) { - struct stat info; - if (stat(input.c_str(), &info) != 0) { - LOG_ERROR("Input file [%s] isn't accessible", input.c_str()); - return false; - } - } - - // All good - return true; -} - -std::string Configuration::GetInputPath(std::string file_name) const { - auto name = file_name + "." + suffix; - return data_dir + - (data_dir[data_dir.length() - 1] == '/' ? name : "/" + name); -} - -std::string Configuration::GetCustomerPath() const { - return GetInputPath("customer"); -} - -std::string Configuration::GetLineitemPath() const { - return GetInputPath("lineitem"); -} - -std::string Configuration::GetNationPath() const { - return GetInputPath("nation"); -} - -std::string Configuration::GetOrdersPath() const { - return GetInputPath("orders"); -} - -std::string Configuration::GetPartSuppPath() const { - return GetInputPath("partsupp"); -} - -std::string Configuration::GetPartPath() const { return GetInputPath("part"); } - -std::string Configuration::GetSupplierPath() const { - return GetInputPath("supplier"); -} - -std::string Configuration::GetRegionPath() const { - return GetInputPath("region"); -} - -void Configuration::SetRunnableQueries(char *query_list) { - // Disable all queries - for (uint32_t i = 0; i < 22; i++) queries_to_run[i] = false; - - // Now pull out the queries the user actually wants to run - char *ptr = strtok(query_list, ","); - while (ptr != nullptr) { - int query = atoi(ptr); - if (query >= 1 && query <= 22) { - queries_to_run[query - 1] = true; - } - ptr = strtok(nullptr, ","); - } -} - -bool Configuration::ShouldRunQuery(QueryId qid) const { - return queries_to_run[static_cast(qid)]; -} - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/main/tpch/tpch_database.cpp b/src/main/tpch/tpch_database.cpp deleted file mode 100644 index 4c93c91c4dd..00000000000 --- a/src/main/tpch/tpch_database.cpp +++ /dev/null @@ -1,690 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_database.cpp -// -// Identification: src/main/tpch/tpch_database.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/tpch/tpch_database.h" - -#include "benchmark/tpch/tpch_workload.h" -#include "catalog/catalog.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -// The TPCH database ID and each of the tables it owns -static constexpr oid_t kTPCHDatabaseId = 44; - -//===----------------------------------------------------------------------===// -// Utility function to run a function over every line in the given file -//===----------------------------------------------------------------------===// -void ForEachLine(const std::string fname, std::function cb) { - // Open the file and advise the kernel of sequential access pattern - int input_fd = open(fname.c_str(), O_RDONLY); - - const uint32_t BUFFER_SIZE = 16 * 1024; - char buffer[BUFFER_SIZE] = {0}; - char *buf_pos = buffer; - - size_t bytes_to_read = BUFFER_SIZE; - ssize_t bytes_read; - while ((bytes_read = read(input_fd, buf_pos, bytes_to_read)) != 0) { - if (bytes_read == -1) { - perror("Error reading from input file"); - close(input_fd); - exit(errno); - } - - char *end = buf_pos + bytes_read; - - char *line_start = buffer; - char *next_line_start; - while ((next_line_start = strchr(line_start, '\n')) != nullptr && - next_line_start < end) { - // Invoke callback on start of line - cb(line_start); - - if (next_line_start == end - 1) { - line_start = end; - break; - } - - line_start = next_line_start + 1; - } - - bytes_to_read = BUFFER_SIZE; - buf_pos = buffer; - - size_t tail_size = end - line_start; - if (tail_size > 0) { - PELOTON_MEMCPY(buffer, line_start, tail_size); - buf_pos = buffer + tail_size; - bytes_to_read -= tail_size; - } - } - close(input_fd); -} - -// Convert the given string into a i32 date -uint32_t ConvertDate(char *p) { - std::tm t_shipdate; - PELOTON_MEMSET(&t_shipdate, 0, sizeof(std::tm)); - strptime(p, "%Y-%m-%d", &t_shipdate); - t_shipdate.tm_isdst = -1; - return static_cast(mktime(&t_shipdate)); -} - -//===----------------------------------------------------------------------===// -// TPCH DATABASE -//===----------------------------------------------------------------------===// - -TPCHDatabase::TPCHDatabase(const Configuration &c) : config_(c) { - // Create database instance - auto *database = new storage::Database(kTPCHDatabaseId); - - // Add databse instance to catalog - catalog::Catalog::GetInstance()->AddDatabase(database); - - // Create all the test table - CreateTables(); - - // Mark all tables as not loaded - for (uint32_t i = 0; i < 8; i++) { - loaded_tables_[i] = false; - } -} - -TPCHDatabase::~TPCHDatabase() { - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto *txn = txn_manager.BeginTransaction(); - catalog::Catalog::GetInstance()->DropDatabaseWithOid(kTPCHDatabaseId, txn); - txn_manager.CommitTransaction(txn); -} - -// Create all the TPCH tables -void TPCHDatabase::CreateTables() const { - // Create all table instances - CreateCustomerTable(); - CreateLineitemTable(); - CreateNationTable(); - CreateOrdersTable(); - CreatePartTable(); - CreatePartSupplierTable(); - CreateRegionTable(); - CreateSupplierTable(); -} - -storage::Database &TPCHDatabase::GetDatabase() const { - auto *catalog = catalog::Catalog::GetInstance(); - return *catalog->GetDatabaseWithOid(kTPCHDatabaseId); -} - -storage::DataTable &TPCHDatabase::GetTable(TableId table_id) const { - return *GetDatabase().GetTableWithOid(static_cast(table_id)); -} - -uint32_t TPCHDatabase::DictionaryEncode(Dictionary &dict, - const std::string &val) { - auto iter = dict.find(val); - if (iter == dict.end()) { - uint32_t code = dict.size(); - dict.insert(std::make_pair(val, code)); - return code; - } else { - return iter->second; - } -} - -uint32_t TPCHDatabase::CodeForMktSegment(const std::string mktsegment) const { - auto iter = c_mktsegment_dict_.find(mktsegment); - return iter != c_mktsegment_dict_.end() ? iter->second : 0; -} - -//===----------------------------------------------------------------------===// -// TABLE CREATORS -//===----------------------------------------------------------------------===// - -void TPCHDatabase::CreateCustomerTable() const { - catalog::Column c_custkey = {type::TypeId::INTEGER, kIntSize, - "c_custkey", true}; - catalog::Column c_name = {type::TypeId::VARCHAR, 25, "c_name", false}; - catalog::Column c_address = {type::TypeId::VARCHAR, 40, "c_address", - false}; - catalog::Column c_nationkey = {type::TypeId::INTEGER, kIntSize, - "c_nationkey", true}; - catalog::Column c_phone = {type::TypeId::VARCHAR, 15, "c_phone", false}; - catalog::Column c_acctbal = {type::TypeId::DECIMAL, kDecimalSize, - "c_acctbal", true}; - catalog::Column c_mktsegment; - if (config_.dictionary_encode) { - c_mktsegment = {type::TypeId::INTEGER, kIntSize, "c_mktsegment", - true}; - } else { - c_mktsegment = {type::TypeId::VARCHAR, 10, "c_mktsegment", true}; - } - catalog::Column c_comment = {type::TypeId::VARCHAR, 117, "c_comment", - false}; - - auto customer_cols = {c_custkey, c_name, c_address, c_nationkey, - c_phone, c_acctbal, c_mktsegment, c_comment}; - - // Create the schema - std::unique_ptr customer_schema{ - new catalog::Schema{customer_cols}}; - - // Create the table! - bool owns_schema = true; - bool adapt_table = true; - storage::DataTable *customer_table = storage::TableFactory::GetDataTable( - kTPCHDatabaseId, (uint32_t)TableId::Customer, customer_schema.release(), - "Customer", config_.tuples_per_tile_group, owns_schema, adapt_table); - - // Add the table to the database (we're releasing ownership at this point) - GetDatabase().AddTable(customer_table); -} - -void TPCHDatabase::CreateLineitemTable() const { - // Define columns - catalog::Column l_orderkey = {type::TypeId::INTEGER, kIntSize, "l_orderkey"}; - catalog::Column l_partkey = {type::TypeId::INTEGER, kIntSize, "l_partkey"}; - catalog::Column l_suppkey = {type::TypeId::INTEGER, kIntSize, "l_suppkey"}; - catalog::Column l_linenumber = {type::TypeId::INTEGER, kIntSize, "l_linenumber"}; - catalog::Column l_quantity = {type::TypeId::INTEGER, kIntSize, "l_quantity"}; - catalog::Column l_extendedprice = {type::TypeId::DECIMAL, kDecimalSize, "l_extendedprice"}; - catalog::Column l_discount = {type::TypeId::DECIMAL, kDecimalSize, "l_discount"}; - catalog::Column l_tax = {type::TypeId::DECIMAL, kDecimalSize, "l_tax"}; - - catalog::Column l_returnflag; - if (config_.dictionary_encode) { - l_returnflag = {type::TypeId::INTEGER, kIntSize, "l_returnflag"}; - } else { - l_returnflag = {type::TypeId::VARCHAR, 1, "l_returnflag"}; - }; - - catalog::Column l_linestatus; - if (config_.dictionary_encode) { - l_linestatus = {type::TypeId::INTEGER, kIntSize, "l_linestatus"}; - } else { - l_linestatus = {type::TypeId::VARCHAR, 1, "l_returnflag"}; - } - - catalog::Column l_shipdate = {type::TypeId::DATE, kDateSize, "l_shipdate"}; - catalog::Column l_commitdate = {type::TypeId::DATE, kDateSize, "l_commitdate"}; - catalog::Column l_receiptdate = {type::TypeId::DATE, kDateSize, "l_receiptdate"}; - catalog::Column l_shipinstruct = {type::TypeId::INTEGER, kIntSize, "l_shipinstruct"}; - catalog::Column l_shipmode = {type::TypeId::INTEGER, kIntSize, "l_shipmode"}; - catalog::Column l_comment = {type::TypeId::VARCHAR, 44, "l_comment"}; - - auto lineitem_cols = { - l_orderkey, l_partkey, l_suppkey, l_linenumber, - l_quantity, l_extendedprice, l_discount, l_tax, - l_returnflag, l_linestatus, l_shipdate, l_commitdate, - l_receiptdate, l_shipinstruct, l_shipmode, l_comment}; - - // Create the schema - std::unique_ptr lineitem_schema{ - new catalog::Schema{lineitem_cols}}; - - // Create the table! - bool owns_schema = true; - bool adapt_table = true; - storage::DataTable *lineitem_table = storage::TableFactory::GetDataTable( - kTPCHDatabaseId, (uint32_t)TableId::Lineitem, lineitem_schema.release(), - "Line Item", config_.tuples_per_tile_group, owns_schema, adapt_table); - - // Add the table to the database (we're releasing ownership at this point) - GetDatabase().AddTable(lineitem_table); -} - -void TPCHDatabase::CreateNationTable() const { - catalog::Column n_nationkey = {type::TypeId::INTEGER, kIntSize, - "n_nationkey", true}; - catalog::Column n_name = {type::TypeId::VARCHAR, 25, "n_name", false}; - catalog::Column n_regionKey = {type::TypeId::INTEGER, kIntSize, "n_regionkey", - true}; - - catalog::Column n_comment = {type::TypeId::VARCHAR, 152, "n_comment", - false}; - - // Create the schema - auto nation_cols = {n_nationkey, n_name, n_regionKey, n_comment}; - std::unique_ptr nation_schema{new catalog::Schema{nation_cols}}; - - // Create the table! - bool owns_schema = true; - bool adapt_table = true; - storage::DataTable *nation_table = storage::TableFactory::GetDataTable( - kTPCHDatabaseId, (uint32_t)TableId::Nation, nation_schema.release(), "Nation", - config_.tuples_per_tile_group, owns_schema, adapt_table); - - // Add the table to the database (we're releasing ownership at this point) - GetDatabase().AddTable(nation_table); -} - -void TPCHDatabase::CreateOrdersTable() const { - catalog::Column o_orderkey = {type::TypeId::INTEGER, kIntSize, - "o_orderkey", true}; - catalog::Column o_custkey = {type::TypeId::INTEGER, kIntSize, - "o_custkey", true}; - catalog::Column o_orderstatus = {type::TypeId::VARCHAR, 1, - "o_orderstatus", true}; - catalog::Column o_totalprice = {type::TypeId::DECIMAL, kDecimalSize, - "o_totalprice", true}; - catalog::Column o_orderdate = {type::TypeId::DATE, kDateSize, - "o_orderdate", true}; - catalog::Column o_orderpriority = {type::TypeId::VARCHAR, 15, - "o_orderpriority", false}; - catalog::Column o_clerk = {type::TypeId::VARCHAR, 15, "o_clerk", false}; - catalog::Column o_shippriority = {type::TypeId::INTEGER, kIntSize, - "o_shippriority", true}; - catalog::Column o_comment = {type::TypeId::VARCHAR, 79, "o_comment", - true}; - - // Create the schema - auto orders_cols = {o_orderkey, o_custkey, o_orderstatus, - o_totalprice, o_orderdate, o_orderpriority, - o_clerk, o_shippriority, o_comment}; - std::unique_ptr order_schema{ - new catalog::Schema{orders_cols}}; - - // Create the table! - bool owns_schema = true; - bool adapt_table = true; - storage::DataTable *order_table = storage::TableFactory::GetDataTable( - kTPCHDatabaseId, (uint32_t)TableId::Orders, order_schema.release(), - "Orders", config_.tuples_per_tile_group, owns_schema, adapt_table); - - // Add the table to the database (we're releasing ownership at this point) - GetDatabase().AddTable(order_table); -} - -void TPCHDatabase::CreatePartTable() const { - catalog::Column p_parkey = {type::TypeId::INTEGER, kIntSize, - "p_partkey", true}; - catalog::Column p_name = {type::TypeId::VARCHAR, 55, "p_name", false}; - catalog::Column p_mfgr = {type::TypeId::VARCHAR, 25, "p_mfgr", false}; - - catalog::Column p_brand; - if (config_.dictionary_encode) { - p_brand = {type::TypeId::INTEGER, kIntSize, "p_brand", true}; - } else { - p_brand = {type::TypeId::VARCHAR, 10, "p_brand", true}; - } - - catalog::Column p_type = {type::TypeId::VARCHAR, 25, "p_type", true}; - catalog::Column p_size = {type::TypeId::INTEGER, kIntSize, "p_size", - true}; - - catalog::Column p_container; - if (config_.dictionary_encode) { - p_container = {type::TypeId::INTEGER, kIntSize, "p_container", true}; - } else { - p_container = {type::TypeId::VARCHAR, 10, "p_container", true}; - } - - catalog::Column p_retailprice = {type::TypeId::DECIMAL, kDecimalSize, - "p_retailprice", true}; - catalog::Column p_comment = {type::TypeId::VARCHAR, 23, "p_comment", - false}; - - // Create the schema - auto part_cols = {p_parkey, p_name, p_mfgr, p_brand, p_type, - p_size, p_container, p_retailprice, p_comment}; - std::unique_ptr part_schema{new catalog::Schema{part_cols}}; - - // Create the table! - bool owns_schema = true; - bool adapt_table = true; - storage::DataTable *part_table = storage::TableFactory::GetDataTable( - kTPCHDatabaseId, (uint32_t)TableId::Part, part_schema.release(), "Part", - config_.tuples_per_tile_group, owns_schema, adapt_table); - - // Add the table to the database (we're releasing ownership at this point) - GetDatabase().AddTable(part_table); -} - -void TPCHDatabase::CreatePartSupplierTable() const {} - -void TPCHDatabase::CreateRegionTable() const {} - -void TPCHDatabase::CreateSupplierTable() const {} - -//===----------------------------------------------------------------------===// -// TABLE LOADERS -//===----------------------------------------------------------------------===// - -void TPCHDatabase::LoadTable(TableId table_id) { - switch (table_id) { - case TableId::Customer: LoadCustomerTable(); break; - case TableId::Lineitem: LoadLineitemTable(); break; - case TableId::Nation: LoadNationTable(); break; - case TableId::Orders: LoadOrdersTable(); break; - case TableId::Part: LoadPartTable(); break; - case TableId::PartSupp: LoadPartSupplierTable(); break; - case TableId::Region: LoadRegionTable(); break; - case TableId::Supplier: LoadSupplierTable(); break; - } -} - -void TPCHDatabase::LoadPartTable() { - if (TableIsLoaded(TableId::Part)) { - return; - } - - const std::string filename = config_.GetPartPath(); - - LOG_INFO("Loading Part ['%s']\n", filename.c_str()); - - auto &table = GetTable(TableId::Part); - - Timer> timer; - timer.Start(); - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto *txn = txn_manager.BeginTransaction(); - - uint64_t num_tuples = 0; - std::unique_ptr pool{new type::EphemeralPool()}; - - ForEachLine(filename, [&](char *p){ - storage::Tuple tuple{table.GetSchema(), true /* allocate */}; - - tuple.SetValue(0, type::ValueFactory::GetIntegerValue(std::atoi(p))); - - p = strchr(p, '|') + 1; - char *p_end = strchr(p, '|'); - tuple.SetValue(1, type::ValueFactory::GetVarcharValue(std::string{p, p_end}), pool.get()); - - p = p_end + 1; - p_end = strchr(p, '|'); - tuple.SetValue(2, type::ValueFactory::GetVarcharValue(std::string{p, p_end}), pool.get()); - - p = p_end + 1; - p_end = strchr(p, '|'); - std::string p_brand{p, p_end}; - if (config_.dictionary_encode) { - uint32_t code = DictionaryEncode(p_brand_dict_, p_brand); - tuple.SetValue(3, type::ValueFactory::GetIntegerValue(code)); - } else { - tuple.SetValue(3, type::ValueFactory::GetVarcharValue(p_brand), pool.get()); - } - - p = p_end + 1; - p_end = strchr(p, '|'); - tuple.SetValue(4, type::ValueFactory::GetVarcharValue(std::string{p, p_end}), pool.get()); - - p = p_end + 1; - tuple.SetValue(5, type::ValueFactory::GetIntegerValue(std::atoi(p))); - - p = p_end + 1; - p_end = strchr(p, '|'); - std::string p_container{p, p_end}; - if (config_.dictionary_encode) { - uint32_t code = DictionaryEncode(p_container_dict_, p_brand); - tuple.SetValue(6, type::ValueFactory::GetIntegerValue(code)); - } else { - tuple.SetValue(6, type::ValueFactory::GetVarcharValue(p_container), pool.get()); - } - - p = p_end + 1; - tuple.SetValue(7, type::ValueFactory::GetDecimalValue(std::atof(p))); - - p = p_end + 1; - p_end = strchr(p, '|'); - tuple.SetValue(8, type::ValueFactory::GetVarcharValue(std::string{p, p_end}), pool.get()); - - // Insert into table - ItemPointer tuple_slot_id = table.InsertTuple(&tuple); - PELOTON_ASSERT(tuple_slot_id.block != INVALID_OID); - PELOTON_ASSERT(tuple_slot_id.offset != INVALID_OID); - txn_manager.PerformInsert(txn, tuple_slot_id); - - num_tuples++; - - }); - - // Commit - PELOTON_ASSERT(txn_manager.CommitTransaction(txn) == ResultType::SUCCESS); - - timer.Stop(); - LOG_INFO("Loading Part finished: %.2f ms (%lu tuples)\n", - timer.GetDuration(), num_tuples); - - // Set table as loaded - SetTableIsLoaded(TableId::Part); -} - -void TPCHDatabase::LoadSupplierTable() {} - -void TPCHDatabase::LoadPartSupplierTable() {} - -void TPCHDatabase::LoadCustomerTable() { - if (TableIsLoaded(TableId::Customer)) { - return; - } - - const std::string filename = config_.GetPartPath(); - - LOG_INFO("Loading Customer ['%s']\n", filename.c_str()); - - auto &table = GetTable(TableId::Customer); - - Timer> timer; - timer.Start(); - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto *txn = txn_manager.BeginTransaction(); - - uint64_t num_tuples = 0; - std::unique_ptr pool{new type::EphemeralPool()}; - - ForEachLine(filename, [&](char *p) { - storage::Tuple tuple{table.GetSchema(), true /* allocate */}; - - // C_CUSTKEY - int32_t c_custkey = std::atoi(p); - tuple.SetValue(0, type::ValueFactory::GetIntegerValue(c_custkey)); - - // C_NAME - p = strchr(p, '|') + 1; - char *p_end = strchr(p, '|'); - - std::string c_name{p, p_end}; - tuple.SetValue(1, type::ValueFactory::GetVarcharValue(c_name), pool.get()); - - // C_ADDRESS - p = p_end + 1; - p_end = strchr(p, '|'); - - std::string c_address{p, p_end}; - tuple.SetValue(2, type::ValueFactory::GetVarcharValue(c_address), pool.get()); - - // C_NATIONKEY - p = p_end + 1; - - int32_t c_nationkey = std::atoi(p); - tuple.SetValue(3, type::ValueFactory::GetIntegerValue(c_nationkey)); - - // C_PHONE - p = strchr(p, '|') + 1; - p_end = strchr(p, '|'); - std::string c_phone{p, p_end}; - tuple.SetValue(4, type::ValueFactory::GetVarcharValue(c_phone), pool.get()); - - // C_ACCTBA - p = p_end + 1; - double c_acctba = std::atof(p); - tuple.SetValue(5, type::ValueFactory::GetDecimalValue(c_acctba)); - - // C_MKTSEGMENT - p = strchr(p, '|') + 1; - p_end = strchr(p, '|'); - std::string c_mktsegment{p, p_end}; - if (config_.dictionary_encode) { - uint32_t code = DictionaryEncode(c_mktsegment_dict_, c_mktsegment); - tuple.SetValue(6, type::ValueFactory::GetIntegerValue(code)); - } else { - tuple.SetValue(6, type::ValueFactory::GetVarcharValue(c_mktsegment), pool.get()); - } - - // C_COMMENT - p = p_end + 1; - p_end = strchr(p, '|'); - std::string c_comment{p, p_end}; - tuple.SetValue(7, type::ValueFactory::GetVarcharValue(c_comment), pool.get()); - - // Insert into table - ItemPointer tuple_slot_id = table.InsertTuple(&tuple); - PELOTON_ASSERT(tuple_slot_id.block != INVALID_OID); - PELOTON_ASSERT(tuple_slot_id.offset != INVALID_OID); - txn_manager.PerformInsert(txn, tuple_slot_id); - - num_tuples++; - }); - - // Commit - PELOTON_ASSERT(txn_manager.CommitTransaction(txn) == ResultType::SUCCESS); - - timer.Stop(); - LOG_INFO("Loading Customer finished: %.2f ms (%lu tuples)\n", - timer.GetDuration(), num_tuples); - - // Set table as loaded - SetTableIsLoaded(TableId::Customer); -} - -void TPCHDatabase::LoadNationTable() {} - -void TPCHDatabase::LoadLineitemTable() { - // Short-circuit if table is already loaded - if (TableIsLoaded(TableId::Lineitem)) { - return; - } - - const std::string filename = config_.GetLineitemPath(); - - LOG_INFO("Loading Lineitem ['%s']\n", filename.c_str()); - - uint64_t num_tuples = 0; - - auto &table = GetTable(TableId::Lineitem); - - std::unique_ptr pool{new type::EphemeralPool()}; - - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto *txn = txn_manager.BeginTransaction(); - - Timer> timer; - timer.Start(); - - ForEachLine(filename, [&](char *p) { - // The input tuple - storage::Tuple tuple{table.GetSchema(), /*allocate*/ true}; - - tuple.SetValue(0, type::ValueFactory::GetIntegerValue(std::atoi(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(1, type::ValueFactory::GetIntegerValue(std::atoi(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(2, type::ValueFactory::GetIntegerValue(std::atoi(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(3, type::ValueFactory::GetIntegerValue(std::atoi(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(4, - type::ValueFactory::GetIntegerValue((int32_t)std::atof(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(5, type::ValueFactory::GetDecimalValue(std::atof(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(6, type::ValueFactory::GetDecimalValue(std::atof(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(7, type::ValueFactory::GetDecimalValue(std::atof(p))); - - p = strchr(p, '|') + 1; - char returnflag = *p; - tuple.SetValue(8, type::ValueFactory::GetIntegerValue(returnflag)); - - p = strchr(p, '|') + 1; - char linestatus = *p; - tuple.SetValue(9, type::ValueFactory::GetIntegerValue(linestatus)); - - p = strchr(p, '|') + 1; - tuple.SetValue(10, type::ValueFactory::GetDateValue(ConvertDate(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(11, type::ValueFactory::GetDateValue(ConvertDate(p))); - - p = strchr(p, '|') + 1; - tuple.SetValue(12, type::ValueFactory::GetDateValue(ConvertDate(p))); - - p = strchr(p, '|') + 1; - char *p_end = strchr(p, '|'); - std::string l_shipinstruct{p, p_end}; - if (config_.dictionary_encode) { - uint32_t code = DictionaryEncode(l_shipinstruct_dict_, l_shipinstruct); - tuple.SetValue(13, type::ValueFactory::GetIntegerValue(code), nullptr); - } else { - tuple.SetValue(13, type::ValueFactory::GetVarcharValue(l_shipinstruct), - pool.get()); - } - - p = p_end + 1; - p_end = strchr(p, '|'); - std::string l_shipmode{p, p_end}; - if (config_.dictionary_encode) { - uint32_t code = DictionaryEncode(l_shipmode_dict_, l_shipmode); - tuple.SetValue(14, type::ValueFactory::GetIntegerValue(code)); - } else { - tuple.SetValue(14, type::ValueFactory::GetVarcharValue(l_shipinstruct), - pool.get()); - } - - p = p_end + 1; - p_end = strchr(p, '|'); - tuple.SetValue(15, - type::ValueFactory::GetVarcharValue(std::string{p, p_end}), - pool.get()); - - // Insert into table - ItemPointer tuple_slot_id = table.InsertTuple(&tuple); - PELOTON_ASSERT(tuple_slot_id.block != INVALID_OID); - PELOTON_ASSERT(tuple_slot_id.offset != INVALID_OID); - txn_manager.PerformInsert(txn, tuple_slot_id); - - num_tuples++; - }); - - // Commit - auto res = txn_manager.CommitTransaction(txn); - PELOTON_ASSERT(res == ResultType::SUCCESS); - if (res != ResultType::SUCCESS) { - LOG_ERROR("Could not commit transaction during load!"); - } - - timer.Stop(); - LOG_INFO("Loading Lineitem finished: %.2f ms (%lu tuples)\n", - timer.GetDuration(), num_tuples); - - // Set table as loaded - SetTableIsLoaded(TableId::Lineitem); -} - -void TPCHDatabase::LoadRegionTable() {} - -void TPCHDatabase::LoadOrdersTable() {} - -} // namespace tpch -} // namespace benchmark -} // namespace peloton diff --git a/src/main/tpch/tpch_workload.cpp b/src/main/tpch/tpch_workload.cpp deleted file mode 100644 index d4721d9b080..00000000000 --- a/src/main/tpch/tpch_workload.cpp +++ /dev/null @@ -1,214 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_workload.cpp -// -// Identification: src/main/tpch/tpch_workload.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/tpch/tpch_workload.h" - -#include "codegen/query.h" -#include "concurrency/transaction_manager_factory.h" -#include "executor/plan_executor.h" -#include "planner/abstract_plan.h" -#include "planner/binding_context.h" -#include "codegen/counting_consumer.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -TPCHBenchmark::TPCHBenchmark(const Configuration &config, TPCHDatabase &db) - : config_(config), db_(db) { - query_configs_ = { - {"Q1", - QueryId::Q1, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q2", - QueryId::Q2, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q3", - QueryId::Q3, - {TableId::Lineitem, TableId::Customer, TableId::Orders}, - [&]() { return ConstructQ3Plan(); }}, - - {"Q4", - QueryId::Q4, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q5", - QueryId::Q5, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q6", - QueryId::Q6, - {TableId::Lineitem}, - [&]() { return ConstructQ6Plan(); }}, - - {"Q7", - QueryId::Q7, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q8", - QueryId::Q8, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q9", - QueryId::Q9, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q10", - QueryId::Q10, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q11", - QueryId::Q11, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q12", - QueryId::Q12, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q13", - QueryId::Q13, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q14", - QueryId::Q14, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q15", - QueryId::Q15, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q16", - QueryId::Q16, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q17", - QueryId::Q17, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q18", - QueryId::Q18, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q19", - QueryId::Q19, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q20", - QueryId::Q20, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q21", - QueryId::Q21, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - - {"Q22", - QueryId::Q22, - {TableId::Lineitem}, - [&]() { return ConstructQ1Plan(); }}, - }; -} - -void TPCHBenchmark::RunBenchmark() { - for (uint32_t i = 0; i < 22; i++) { - const auto &query_config = query_configs_[i]; - if (config_.ShouldRunQuery(query_config.query_id)) { - RunQuery(query_config); - } - } -} - -void TPCHBenchmark::RunQuery(const TPCHBenchmark::QueryConfig &query_config) { - LOG_INFO("Running TPCH %s", query_config.query_name.c_str()); - - // Load all the necessary tables - for (auto tid : query_config.required_tables) { - db_.LoadTable(tid); - } - - // Construct the plan for Q1 - std::unique_ptr plan = query_config.PlanConstructor(); - - // Do attribute binding - planner::BindingContext binding_context; - plan->PerformBinding(binding_context); - - // The consumer - codegen::CountingConsumer counter; - - // Compile - codegen::QueryCompiler::CompileStats compile_stats; - codegen::QueryCompiler compiler; - auto compiled_query = compiler.Compile(*plan, counter, &compile_stats); - - codegen::Query::RuntimeStats overall_stats; - overall_stats.init_ms = 0.0; - overall_stats.plan_ms = 0.0; - overall_stats.tear_down_ms = 0.0; - for (uint32_t i = 0; i < config_.num_runs; i++) { - // Reset the counter for this run - counter.ResetCount(); - - // Begin a transaction - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - auto *txn = txn_manager.BeginTransaction(); - - // Execute query in a transaction - codegen::Query::RuntimeStats runtime_stats; - compiled_query->Execute(*txn, counter.GetCountAsState(), &runtime_stats); - - // Commit transaction - txn_manager.CommitTransaction(txn); - - // Collect stats - overall_stats.init_ms += runtime_stats.init_ms; - overall_stats.plan_ms += runtime_stats.plan_ms; - overall_stats.tear_down_ms += runtime_stats.tear_down_ms; - } - - LOG_INFO("%s: %s", - query_config.query_name.c_str(), peloton::GETINFO_THICK_LINE.c_str()); - LOG_INFO("# Runs: %u, # Result tuples: %lu", config_.num_runs, - counter.GetCount()); - LOG_INFO("Setup: %.2lf, IR Gen: %.2lf, Compile: %.2lf", - compile_stats.setup_ms, compile_stats.ir_gen_ms, - compile_stats.jit_ms); - LOG_INFO("Init: %.2lf ms, Plan: %.2lf ms, TearDown: %.2lf ms", - overall_stats.init_ms / config_.num_runs, - overall_stats.plan_ms / config_.num_runs, - overall_stats.tear_down_ms / config_.num_runs); -} - - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/main/tpch/tpch_workload_q1.cpp b/src/main/tpch/tpch_workload_q1.cpp deleted file mode 100644 index 2dd0e2c0f54..00000000000 --- a/src/main/tpch/tpch_workload_q1.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_workload_q1.cpp -// -// Identification: src/main/tpch/tpch_workload_q1.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/tpch/tpch_workload.h" - -#include "concurrency/transaction_manager_factory.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/operator_expression.h" -#include "expression/tuple_value_expression.h" -#include "planner/aggregate_plan.h" -#include "planner/order_by_plan.h" -#include "planner/seq_scan_plan.h" - - -namespace peloton { -namespace benchmark { -namespace tpch { - -static constexpr int32_t _1998_08_28 = 904276800; - -std::unique_ptr TPCHBenchmark::ConstructQ1Plan() const { - auto &lineitem = db_.GetTable(TableId::Lineitem); - - ////////////////////////////////////////////////////////////////////////////// - /// THE PREDICATE FOR THE SCAN OVER LINEITEM - ////////////////////////////////////////////////////////////////////////////// - - auto shipdate_predicate = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_LESSTHANOREQUALTO, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, - 10), - new expression::ConstantValueExpression( - type::ValueFactory::GetDateValue(_1998_08_28)))}; - - ////////////////////////////////////////////////////////////////////////////// - /// THE SCAN PLAN - ////////////////////////////////////////////////////////////////////////////// - - // Lineitem scan - std::unique_ptr lineitem_scan{new planner::SeqScanPlan( - &lineitem, shipdate_predicate.release(), {8, 9, 4, 5, 6, 7})}; - - ////////////////////////////////////////////////////////////////////////////// - /// THE AGGREGATION PLAN - ///////////////////////////////////////////////////////////////////////////// - - // sum(l_quantity) as sum_qty - planner::AggregatePlan::AggTerm agg1{ - ExpressionType::AGGREGATE_SUM, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 2)}; - agg1.agg_ai.type = type::TypeId::INTEGER; - - // sum(l_extendedprice) as sum_base_price - planner::AggregatePlan::AggTerm agg2{ - ExpressionType::AGGREGATE_SUM, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 3)}; - agg2.agg_ai.type = type::TypeId::DECIMAL; - - // sum(l_extendedprice * (1 - l_discount)) as sum_disc_price - planner::AggregatePlan::AggTerm agg3{ - ExpressionType::AGGREGATE_SUM, - new expression::OperatorExpression( - ExpressionType::OPERATOR_MULTIPLY, type::TypeId::DECIMAL, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, - 3), - new expression::OperatorExpression( - ExpressionType::OPERATOR_MINUS, type::TypeId::DECIMAL, - new expression::ConstantValueExpression( - type::ValueFactory::GetDecimalValue(1.0)), - new expression::TupleValueExpression(type::TypeId::DECIMAL, - 0, 4)))}; - agg3.agg_ai.type = type::TypeId::DECIMAL; - - // sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) - planner::AggregatePlan::AggTerm agg4{ - ExpressionType::AGGREGATE_SUM, - new expression::OperatorExpression( - ExpressionType::OPERATOR_MULTIPLY, type::TypeId::DECIMAL, - // l_extendedprice - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, - 3), - // (1 - l_discount) * (1 + l_tax) - new expression::OperatorExpression( - ExpressionType::OPERATOR_MULTIPLY, type::TypeId::DECIMAL, - // 1 - l_discount - new expression::OperatorExpression( - ExpressionType::OPERATOR_MINUS, type::TypeId::DECIMAL, - new expression::ConstantValueExpression( - type::ValueFactory::GetDecimalValue(1.0)), - new expression::TupleValueExpression( - type::TypeId::DECIMAL, 0, 4)), - // 1 + l_tax - new expression::OperatorExpression( - ExpressionType::OPERATOR_PLUS, type::TypeId::DECIMAL, - new expression::ConstantValueExpression( - type::ValueFactory::GetDecimalValue(1.0)), - new expression::TupleValueExpression( - type::TypeId::DECIMAL, 0, 5))))}; - agg4.agg_ai.type = type::TypeId::DECIMAL; - - // avg(l_quantity) - planner::AggregatePlan::AggTerm agg5{ - ExpressionType::AGGREGATE_AVG, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 2)}; - agg5.agg_ai.type = type::TypeId::DECIMAL; - - // avg(l_extendedprice) - planner::AggregatePlan::AggTerm agg6{ - ExpressionType::AGGREGATE_AVG, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 3)}; - agg6.agg_ai.type = type::TypeId::DECIMAL; - - // avg(l_discount) - planner::AggregatePlan::AggTerm agg7{ - ExpressionType::AGGREGATE_AVG, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 4)}; - agg7.agg_ai.type = type::TypeId::DECIMAL; - - // count(*) - planner::AggregatePlan::AggTerm agg8{ExpressionType::AGGREGATE_COUNT_STAR, - nullptr}; - agg8.agg_ai.type = type::TypeId::BIGINT; - - auto output_schema = - std::shared_ptr{new catalog::Schema( - {{type::TypeId::INTEGER, kIntSize, "l_returnflag"}, - {type::TypeId::INTEGER, kIntSize, "l_linestatus"}, - {type::TypeId::INTEGER, kIntSize, "sum_qty"}, - {type::TypeId::DECIMAL, kDecimalSize, "sum_base_price"}, - {type::TypeId::DECIMAL, kDecimalSize, "sum_disc_price"}, - {type::TypeId::DECIMAL, kDecimalSize, "sum_charge"}, - {type::TypeId::DECIMAL, kDecimalSize, "avg_qty"}, - {type::TypeId::DECIMAL, kDecimalSize, "avg_price"}, - {type::TypeId::DECIMAL, kDecimalSize, "avg_disc"}, - {type::TypeId::BIGINT, kBigIntSize, "count_order"}})}; - - DirectMapList dml = {{0, {0, 0}}, {1, {0, 1}}, {2, {1, 0}}, {3, {1, 1}}, - {4, {1, 2}}, {5, {1, 3}}, {6, {1, 4}}, {7, {1, 5}}, - {8, {1, 6}}, {9, {1, 7}}}; - - std::unique_ptr agg_project{ - new planner::ProjectInfo(TargetList{}, std::move(dml))}; - auto agg_terms = {agg1, agg2, agg3, agg4, agg5, agg6, agg7, agg8}; - std::unique_ptr agg_plan{new planner::AggregatePlan( - std::move(agg_project), nullptr, std::move(agg_terms), {0, 1}, - output_schema, AggregateType::HASH)}; - - std::unique_ptr sort_plan{new planner::OrderByPlan{ - {0, 1}, {false, false}, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}}; - - agg_plan->AddChild(std::move(lineitem_scan)); - sort_plan->AddChild(std::move(agg_plan)); - - return sort_plan; -} - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/main/tpch/tpch_workload_q3.cpp b/src/main/tpch/tpch_workload_q3.cpp deleted file mode 100644 index 98a41e01b1e..00000000000 --- a/src/main/tpch/tpch_workload_q3.cpp +++ /dev/null @@ -1,253 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_workload_q3.cpp -// -// Identification: src/main/tpch/tpch_workload_q3.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/tpch/tpch_workload.h" - -#include "concurrency/transaction_manager_factory.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/operator_expression.h" -#include "expression/tuple_value_expression.h" -#include "planner/aggregate_plan.h" -#include "planner/hash_join_plan.h" -#include "planner/hash_plan.h" -#include "planner/order_by_plan.h" -#include "planner/projection_plan.h" -#include "planner/seq_scan_plan.h" - -namespace peloton { -namespace benchmark { -namespace tpch { - -static int32_t _1995_03_10 = 794811600; - -std::unique_ptr TPCHBenchmark::ConstructQ3Plan() const { - auto &lineitem = db_.GetTable(TableId::Lineitem); - auto &customer = db_.GetTable(TableId::Customer); - auto &orders = db_.GetTable(TableId::Orders); - - ////////////////////////////////////////////////////////////////////////////// [3136/4535] - /// THE PREDICATE FOR THE SCAN OVER LINEITEM - ////////////////////////////////////////////////////////////////////////////// - - uint32_t machinery = db_.CodeForMktSegment("MACHINERY"); - - auto orderdate_pred = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_LESSTHANOREQUALTO, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 4), - new expression::ConstantValueExpression(type::ValueFactory::GetDateValue(_1995_03_10)))}; - - auto mktsegment_pred = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_EQUAL, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 6), - new expression::ConstantValueExpression(type::ValueFactory::GetIntegerValue(machinery)))}; - - auto shipdate_pred = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_GREATERTHAN, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 10), - new expression::ConstantValueExpression(type::ValueFactory::GetDateValue(_1995_03_10)))}; - - ////////////////////////////////////////////////////////////////////////////// - /// THE SCAN PLANS - ////////////////////////////////////////////////////////////////////////////// - - // The table scans - std::unique_ptr lineitem_scan{ - new planner::SeqScanPlan(&lineitem, shipdate_pred.release(), {0,5,6})}; - std::unique_ptr order_scan{ - new planner::SeqScanPlan(&orders, orderdate_pred.release(), {0,1,4,7})}; - std::unique_ptr customer_scan{ - new planner::SeqScanPlan(&customer, mktsegment_pred.release(), {0})}; - - ////////////////////////////////////////////////////////////////////////////// - /// REARRANGE ORDERS COLUMNS FOR JOIN - ////////////////////////////////////////////////////////////////////////////// - - DirectMap dmo1 = std::make_pair(0, std::make_pair(0, 1)); - DirectMap dmo2 = std::make_pair(1, std::make_pair(0, 0)); - DirectMap dmo3 = std::make_pair(2, std::make_pair(0, 2)); - DirectMap dmo4 = std::make_pair(3, std::make_pair(0, 3)); - DirectMapList order_dm = {dmo1, dmo2, dmo3, dmo4}; - - std::unique_ptr order_project_info{ - new planner::ProjectInfo(TargetList{}, std::move(order_dm))}; - auto order_schema = std::shared_ptr(new catalog::Schema( - {{type::TypeId::INTEGER, kIntSize, "o_custkey", true}, - {type::TypeId::INTEGER, kIntSize, "o_orderkey", true}, - {type::TypeId::DATE, kDateSize, "o_orderdate", true}, - {type::TypeId::INTEGER, kIntSize, "o_shippriority", true}})); - std::unique_ptr order_projection{ - new planner::ProjectionPlan(std::move(order_project_info), order_schema)}; - - ////////////////////////////////////////////////////////////////////////////// - /// Customer - Order HASH PLAN - ////////////////////////////////////////////////////////////////////////////// - - std::vector> hash_keys; - hash_keys.emplace_back( - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 0)); - - std::unique_ptr customer_hash_plan{new planner::HashPlan(hash_keys)}; - - ////////////////////////////////////////////////////////////////////////////// - /// Customer - Order JOIN - ////////////////////////////////////////////////////////////////////////////// - - DirectMap dm1 = std::make_pair(0, std::make_pair(0, 1)); - DirectMap dm2 = std::make_pair(1, std::make_pair(0, 2)); - DirectMap dm3 = std::make_pair(2, std::make_pair(0, 3)); - DirectMapList direct_map_list = {dm1, dm2, dm3}; - - std::unique_ptr projection{new planner::ProjectInfo( - TargetList{}, std::move(direct_map_list))}; - - auto schema = std::shared_ptr(new catalog::Schema( - {{type::TypeId::INTEGER, kIntSize, "o_orderkey", true}, - {type::TypeId::DATE, kDateSize, "o_orderdate", true}, - {type::TypeId::INTEGER, kIntSize, "o_shippriority", true}})); - - std::vector> left_hash_keys; - left_hash_keys.emplace_back( - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 1)); - - std::vector> right_hash_keys; - right_hash_keys.emplace_back( - new expression::TupleValueExpression(type::TypeId::INTEGER, 1, 0)); - - std::unique_ptr cust_order_hj_plan{new planner::HashJoinPlan( - JoinType::INNER, nullptr, std::move(projection), - schema, left_hash_keys, right_hash_keys)}; - - ////////////////////////////////////////////////////////////////////////////// - /// ORDER - LINITEM HASH PLAN - ////////////////////////////////////////////////////////////////////////////// - - std::vector> hash_keys2; - hash_keys2.emplace_back( - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 0)); - - std::unique_ptr cust_order_hash_plan{new planner::HashPlan(hash_keys2)}; - - ////////////////////////////////////////////////////////////////////////////// - /// ORDER - LINEITEM JOIN - ////////////////////////////////////////////////////////////////////////////// - - DirectMap dm12 = std::make_pair(0, std::make_pair(0, 0)); - DirectMap dm22 = std::make_pair(1, std::make_pair(0, 1)); - DirectMap dm32 = std::make_pair(2, std::make_pair(0, 2)); - DirectMap dm42 = std::make_pair(3, std::make_pair(1, 0)); - DirectMap dm52 = std::make_pair(4, std::make_pair(1, 1)); - DirectMap dm62 = std::make_pair(5, std::make_pair(1, 2)); - DirectMapList dm_ol = {dm12, dm22, dm32, dm42, dm52, dm62}; - - std::unique_ptr projection2{new planner::ProjectInfo( - TargetList{}, std::move(dm_ol))}; - - auto ol_schema = std::shared_ptr(new catalog::Schema( - {{type::TypeId::INTEGER, kIntSize, "l_orderkey", true}, - {type::TypeId::DECIMAL, kDecimalSize, "l_extendedprice", true}, - {type::TypeId::DECIMAL, kDecimalSize, "l_discount", true}, - {type::TypeId::INTEGER, kIntSize, "o_orderkey", true}, - {type::TypeId::DATE, kDateSize, "o_shipddate", true}, - {type::TypeId::INTEGER, kIntSize, "o_shippriority", true}})); - - std::vector> left_hash_keys2; - left_hash_keys2.emplace_back( - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 1)); - - std::vector> right_hash_keys2; - right_hash_keys2.emplace_back( - new expression::TupleValueExpression(type::TypeId::INTEGER, 1, 0)); - - std::unique_ptr hj_plan2{new planner::HashJoinPlan( - JoinType::INNER, nullptr, std::move(projection2), - ol_schema, left_hash_keys2, right_hash_keys2)}; - - ////////////////////////////////////////////////////////////////////////////// - /// AGGREGATION - ////////////////////////////////////////////////////////////////////////////// - planner::AggregatePlan::AggTerm agg1{ - ExpressionType::AGGREGATE_SUM, - new expression::OperatorExpression{ - ExpressionType::OPERATOR_MULTIPLY, type::TypeId::DECIMAL, - new expression::TupleValueExpression{type::TypeId::DECIMAL, 0, 1}, - new expression::OperatorExpression{ - ExpressionType::OPERATOR_MINUS, type::TypeId::DECIMAL, - new expression::ConstantValueExpression{type::ValueFactory::GetDecimalValue(1.0)}, - new expression::TupleValueExpression{type::TypeId::DECIMAL, 0, 2} - } - } - }; - auto agg_out_schema = std::shared_ptr{ - new catalog::Schema{ - {{type::TypeId::INTEGER, kIntSize, "l_orderkey", true}, - {type::TypeId::DATE, kDateSize, "o_orderdate", true}, - {type::TypeId::INTEGER, kIntSize, "o_shippriority", true}, - {type::TypeId::DECIMAL, kDecimalSize, "revenue", true}} - } - }; - - DirectMapList dml = { - {0, {0, 0}}, {1, {0, 4}}, {2, {0, 5}}, {3, {1, 0}} - }; - std::unique_ptr agg_project{ - new planner::ProjectInfo(TargetList{}, std::move(dml))}; - std::unique_ptr agg_plan{ - new planner::AggregatePlan(std::move(agg_project), nullptr, - {agg1}, {0, 4, 5}, agg_out_schema, - AggregateType::HASH)}; - - ////////////////////////////////////////////////////////////////////////////// - /// SORT - ////////////////////////////////////////////////////////////////////////////// - - std::unique_ptr sort_plan{ - new planner::OrderByPlan{{3,1}, {false, false}, {0,1,2,3}} - }; - - ////////////////////////////////////////////////////////////////////////////// - /// TIE THE SHIT UP - ////////////////////////////////////////////////////////////////////////////// - - // Build hash on customer - customer_hash_plan->AddChild(std::move(customer_scan)); - - // Project order - order_projection->AddChild(std::move(order_scan)); - - // Customer x Orders hash join (from convention, build goes on right) - cust_order_hj_plan->AddChild(std::move(order_projection)); - cust_order_hj_plan->AddChild(std::move(customer_hash_plan)); - - // Build hash on output of cust x order - cust_order_hash_plan->AddChild(std::move(cust_order_hj_plan)); - - // Final join - hj_plan2->AddChild(std::move(lineitem_scan)); - hj_plan2->AddChild(std::move(cust_order_hash_plan)); - - // Aggregation on output of join - agg_plan->AddChild(std::move(hj_plan2)); - - // Sort final results - sort_plan->AddChild(std::move(agg_plan)); - - return sort_plan; - -} - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/main/tpch/tpch_workload_q6.cpp b/src/main/tpch/tpch_workload_q6.cpp deleted file mode 100644 index 8a1008d7567..00000000000 --- a/src/main/tpch/tpch_workload_q6.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// tpch_workload_q1.cpp -// -// Identification: src/main/tpch/tpch_workload_q1.cpp -// -// Copyright (c) 2015-17, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "benchmark/tpch/tpch_workload.h" - -#include "concurrency/transaction_manager_factory.h" -#include "expression/comparison_expression.h" -#include "expression/conjunction_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/operator_expression.h" -#include "expression/tuple_value_expression.h" -#include "planner/aggregate_plan.h" -#include "planner/order_by_plan.h" -#include "planner/seq_scan_plan.h" - - -namespace peloton { -namespace benchmark { -namespace tpch { - -static constexpr int32_t _1997_01_01 = 852094800; -static constexpr int32_t _1998_01_01 = 883630800; - -std::unique_ptr TPCHBenchmark::ConstructQ6Plan() const { - auto &lineitem = db_.GetTable(TableId::Lineitem); - - ////////////////////////////////////////////////////////////////////////////// - /// THE PREDICATE FOR THE SCAN OVER LINEITEM - ////////////////////////////////////////////////////////////////////////////// - - auto shipdate_gte = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_GREATERTHANOREQUALTO, - new expression::TupleValueExpression(type::TypeId::DATE, 0, 10), - new expression::ConstantValueExpression( - type::ValueFactory::GetDateValue(_1997_01_01)))}; - - auto shipdate_lt = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_LESSTHAN, - new expression::TupleValueExpression(type::TypeId::DATE, 0, 10), - new expression::ConstantValueExpression( - type::ValueFactory::GetDateValue(_1998_01_01)))}; - - auto discount_gt = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_GREATERTHAN, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 6), - new expression::OperatorExpression( - ExpressionType::OPERATOR_MINUS, type::TypeId::DECIMAL, - new expression::ConstantValueExpression(type::ValueFactory::GetDecimalValue(0.07)), - new expression::ConstantValueExpression(type::ValueFactory::GetDecimalValue(0.01)) - ) - ) - }; - - auto discount_lt = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_LESSTHAN, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 6), - new expression::OperatorExpression( - ExpressionType::OPERATOR_PLUS, type::TypeId::DECIMAL, - new expression::ConstantValueExpression(type::ValueFactory::GetDecimalValue(0.07)), - new expression::ConstantValueExpression(type::ValueFactory::GetDecimalValue(0.01)) - ) - ) - }; - - auto quantity_lt = std::unique_ptr{ - new expression::ComparisonExpression( - ExpressionType::COMPARE_LESSTHAN, - new expression::TupleValueExpression(type::TypeId::INTEGER, 0, 4), - new expression::ConstantValueExpression(type::ValueFactory::GetIntegerValue(24)) - ) - }; - - auto lineitem_pred = std::unique_ptr{ - new expression::ConjunctionExpression(ExpressionType::CONJUNCTION_AND, - quantity_lt.release(), - new expression::ConjunctionExpression(ExpressionType::CONJUNCTION_AND, - new expression::ConjunctionExpression(ExpressionType::CONJUNCTION_AND, shipdate_gte.release(), shipdate_lt.release()), - new expression::ConjunctionExpression(ExpressionType::CONJUNCTION_AND, discount_gt.release(), discount_lt.release()) - ) - ) - }; - - ////////////////////////////////////////////////////////////////////////////// - /// THE SCAN PLAN - ////////////////////////////////////////////////////////////////////////////// - - // Lineitem scan - auto lineitem_scan = std::unique_ptr{ - new planner::SeqScanPlan(&lineitem, lineitem_pred.release(), {5,6})}; - - ////////////////////////////////////////////////////////////////////////////// - /// THE GLOBAL AGGREGATION - ////////////////////////////////////////////////////////////////////////////// - - // sum(l_extendedprice * l_discount) as revenue - planner::AggregatePlan::AggTerm revenue_agg{ - ExpressionType::AGGREGATE_SUM, - new expression::OperatorExpression( - ExpressionType::OPERATOR_MULTIPLY, type::TypeId::DECIMAL, - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 0), - new expression::TupleValueExpression(type::TypeId::DECIMAL, 0, 1))}; - revenue_agg.agg_ai.type = type::TypeId::DECIMAL; - - auto output_schema = - std::shared_ptr{new catalog::Schema( - {{type::TypeId::DECIMAL, kDecimalSize, "revenue"}})}; - - DirectMapList dml = {{0, {1, 0}}}; - - std::unique_ptr agg_project{ - new planner::ProjectInfo(TargetList{}, std::move(dml))}; - auto agg_terms = {revenue_agg}; - auto aggregation_plan = std::unique_ptr{ - new planner::AggregatePlan(std::move(agg_project), nullptr, - std::move(agg_terms), {}, output_schema, - AggregateType::HASH)}; - - aggregation_plan->AddChild(std::move(lineitem_scan)); - - return aggregation_plan; -} - -} // namespace tpch -} // namespace benchmark -} // namespace peloton \ No newline at end of file diff --git a/src/main/ycsb/ycsb.cpp b/src/main/ycsb/ycsb.cpp deleted file mode 100644 index 9b748da8ce7..00000000000 --- a/src/main/ycsb/ycsb.cpp +++ /dev/null @@ -1,102 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb.cpp -// -// Identification: src/main/ycsb/ycsb.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===//w - -#include -#include -#include - -#include "common/logger.h" -#include "benchmark/ycsb/ycsb_configuration.h" -#include "benchmark/ycsb/ycsb_loader.h" -#include "benchmark/ycsb/ycsb_workload.h" - -#include "gc/gc_manager_factory.h" -#include "concurrency/epoch_manager_factory.h" - -namespace peloton { -namespace benchmark { -namespace ycsb { - -configuration state; - -// Main Entry Point -void RunBenchmark() { - - if (state.gc_mode == false) { - gc::GCManagerFactory::Configure(0); - } else { - gc::GCManagerFactory::Configure(state.gc_backend_count); - } - - concurrency::EpochManagerFactory::Configure(state.epoch); - - std::unique_ptr epoch_thread; - std::vector> gc_threads; - - concurrency::EpochManager &epoch_manager = concurrency::EpochManagerFactory::GetInstance(); - - if (concurrency::EpochManagerFactory::GetEpochType() == EpochType::DECENTRALIZED_EPOCH) { - for (size_t i = 0; i < (size_t) state.backend_count; ++i) { - // register thread to epoch manager - epoch_manager.RegisterThread(i); - } - } - - // start epoch. - epoch_manager.StartEpoch(epoch_thread); - - gc::GCManager &gc_manager = gc::GCManagerFactory::GetInstance(); - - // start GC. - gc_manager.StartGC(gc_threads); - - // Create the database - CreateYCSBDatabase(); - - // Load the databases - LoadYCSBDatabase(); - - // Run the workload - RunWorkload(); - - // stop GC. - gc_manager.StopGC(); - - // stop epoch. - epoch_manager.StopEpoch(); - - // join all gc threads - for (auto &gc_thread : gc_threads) { - PELOTON_ASSERT(gc_thread != nullptr); - gc_thread->join(); - } - - // join epoch thread - PELOTON_ASSERT(epoch_thread != nullptr); - epoch_thread->join(); - - // Emit throughput - WriteOutput(); -} - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton - -int main(int argc, char **argv) { - peloton::benchmark::ycsb::ParseArguments(argc, argv, - peloton::benchmark::ycsb::state); - - peloton::benchmark::ycsb::RunBenchmark(); - - return 0; -} diff --git a/src/main/ycsb/ycsb_configuration.cpp b/src/main/ycsb/ycsb_configuration.cpp deleted file mode 100644 index 06be5414d55..00000000000 --- a/src/main/ycsb/ycsb_configuration.cpp +++ /dev/null @@ -1,318 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_configuration.cpp -// -// Identification: src/main/ycsb/ycsb_configuration.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#include -#include -#include -#include - -#include "benchmark/ycsb/ycsb_configuration.h" -#include "common/logger.h" - -namespace peloton { -namespace benchmark { -namespace ycsb { - -void Usage(FILE *out) { - fprintf(out, - "Command line options : ycsb \n" - " -h --help : print help message \n" - " -i --index : index type: bwtree (default) \n" - " -k --scale_factor : # of K tuples \n" - " -d --duration : execution duration \n" - " -p --profile_duration : profile duration \n" - " -b --backend_count : # of backends \n" - " -c --column_count : # of columns \n" - " -o --operation_count : # of operations \n" - " -u --update_ratio : fraction of updates \n" - " -z --zipf_theta : theta to control skewness \n" - " -e --exp_backoff : enable exponential backoff \n" - " -m --string_mode : store strings \n" - " -g --gc_mode : enable garbage collection \n" - " -n --gc_backend_count : # of gc backends \n" - " -l --loader_count : # of loaders \n" - " -y --epoch : epoch type: centralized or decentralized \n" - ); -} - -static struct option opts[] = { - { "index", optional_argument, NULL, 'i' }, - { "scale_factor", optional_argument, NULL, 'k' }, - { "duration", optional_argument, NULL, 'd' }, - { "profile_duration", optional_argument, NULL, 'p' }, - { "backend_count", optional_argument, NULL, 'b' }, - { "column_count", optional_argument, NULL, 'c' }, - { "operation_count", optional_argument, NULL, 'o' }, - { "update_ratio", optional_argument, NULL, 'u' }, - { "zipf_theta", optional_argument, NULL, 'z' }, - { "exp_backoff", no_argument, NULL, 'e' }, - { "string_mode", no_argument, NULL, 'm' }, - { "gc_mode", no_argument, NULL, 'g' }, - { "gc_backend_count", optional_argument, NULL, 'n' }, - { "loader_count", optional_argument, NULL, 'n' }, - { "epoch", optional_argument, NULL, 'y' }, - { NULL, 0, NULL, 0 } -}; - -void ValidateIndex(const configuration &state) { - if (state.index != IndexType::BWTREE && state.index != IndexType::BWTREE) { - LOG_ERROR("Invalid index"); - exit(EXIT_FAILURE); - } -} - -void ValidateScaleFactor(const configuration &state) { - if (state.scale_factor <= 0) { - LOG_ERROR("Invalid scale_factor :: %d", state.scale_factor); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "scale_factor", state.scale_factor); -} - -void ValidateDuration(const configuration &state) { - if (state.duration <= 0) { - LOG_ERROR("Invalid duration :: %lf", state.duration); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "duration", state.duration); -} - -void ValidateProfileDuration(const configuration &state) { - if (state.profile_duration <= 0) { - LOG_ERROR("Invalid profile_duration :: %lf", state.profile_duration); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "profile_duration", state.profile_duration); -} - -void ValidateBackendCount(const configuration &state) { - if (state.backend_count <= 0) { - LOG_ERROR("Invalid backend_count :: %d", state.backend_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "backend_count", state.backend_count); -} - -void ValidateColumnCount(const configuration &state) { - if (state.column_count <= 0) { - LOG_ERROR("Invalid column_count :: %d", state.column_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "column_count", state.column_count); -} - -void ValidateOperationCount(const configuration &state) { - if (state.operation_count <= 0) { - LOG_ERROR("Invalid operation_count :: %d", state.operation_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "operation_count", state.operation_count); -} - -void ValidateUpdateRatio(const configuration &state) { - if (state.update_ratio < 0 || state.update_ratio > 1) { - LOG_ERROR("Invalid update_ratio :: %lf", state.update_ratio); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "update_ratio", state.update_ratio); -} - -void ValidateZipfTheta(const configuration &state) { - if (state.zipf_theta < 0 || state.zipf_theta > 1.0) { - LOG_ERROR("Invalid zipf_theta :: %lf", state.zipf_theta); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %lf", "zipf_theta", state.zipf_theta); -} - -void ValidateGCBackendCount(const configuration &state) { - if (state.gc_backend_count <= 0) { - LOG_ERROR("Invalid gc_backend_count :: %d", state.gc_backend_count); - exit(EXIT_FAILURE); - } - - LOG_TRACE("%s : %d", "gc_backend_count", state.gc_backend_count); -} - -void ParseArguments(int argc, char *argv[], configuration &state) { - // Default Values - state.index = IndexType::BWTREE; - state.epoch = EpochType::DECENTRALIZED_EPOCH; - state.scale_factor = 1; - state.duration = 10; - state.profile_duration = 1; - state.backend_count = 2; - state.column_count = 10; - state.operation_count = 10; - state.update_ratio = 0.5; - state.zipf_theta = 0.0; - state.exp_backoff = false; - state.string_mode = false; - state.gc_mode = false; - state.gc_backend_count = 1; - state.loader_count = 1; - - // Parse args - while (1) { - int idx = 0; - int c = getopt_long(argc, argv, "hemgi:k:d:p:b:c:o:u:z:n:l:y:", opts, &idx); - - if (c == -1) break; - - switch (c) { - case 'i': { - char *index = optarg; - if (strcmp(index, "bwtree") == 0) { - state.index = IndexType::BWTREE; - } else { - LOG_ERROR("Unknown index: %s", index); - exit(EXIT_FAILURE); - } - break; - } - case 'y': { - char *epoch = optarg; - if (strcmp(epoch, "decentralized") == 0) { - state.epoch = EpochType::DECENTRALIZED_EPOCH; - } else { - LOG_ERROR("Unknown epoch: %s", epoch); - exit(EXIT_FAILURE); - } - break; - } - case 'l': - state.loader_count = atoi(optarg); - break; - case 'k': - state.scale_factor = atoi(optarg); - break; - case 'd': - state.duration = atof(optarg); - break; - case 'p': - state.profile_duration = atof(optarg); - break; - case 'b': - state.backend_count = atoi(optarg); - break; - case 'c': - state.column_count = atoi(optarg); - break; - case 'o': - state.operation_count = atoi(optarg); - break; - case 'u': - state.update_ratio = atof(optarg); - break; - case 'z': - state.zipf_theta = atof(optarg); - break; - case 'e': - state.exp_backoff = true; - break; - case 'm': - state.string_mode = true; - break; - case 'g': - state.gc_mode = true; - break; - case 'n': - state.gc_backend_count = atoi(optarg); - break; - - case 'h': - Usage(stderr); - exit(EXIT_FAILURE); - break; - - default: - LOG_ERROR("Unknown option: -%c-", c); - Usage(stderr); - exit(EXIT_FAILURE); - break; - } - } - - // Print configuration - ValidateIndex(state); - ValidateScaleFactor(state); - ValidateDuration(state); - ValidateProfileDuration(state); - ValidateBackendCount(state); - ValidateColumnCount(state); - ValidateOperationCount(state); - ValidateUpdateRatio(state); - ValidateZipfTheta(state); - ValidateGCBackendCount(state); - - LOG_TRACE("%s : %d", "Run exponential backoff", state.exp_backoff); - LOG_TRACE("%s : %d", "Run string mode", state.string_mode); - LOG_TRACE("%s : %d", "Run garbage collection", state.gc_mode); - -} - - -void WriteOutput() { - std::ofstream out("outputfile.summary"); - - oid_t total_profile_memory = 0; - for (auto &entry : state.profile_memory) { - total_profile_memory += entry; - } - - LOG_INFO("----------------------------------------------------------"); - LOG_INFO("%d %d %d %d %lf %lf :: %lf %lf %d", - state.scale_factor, - state.backend_count, - state.column_count, - state.operation_count, - state.update_ratio, - state.zipf_theta, - state.throughput, - state.abort_rate, - total_profile_memory); - - out << state.scale_factor << " "; - out << state.backend_count << " "; - out << state.column_count << " "; - out << state.operation_count << " "; - out << state.update_ratio << " "; - out << state.zipf_theta << " "; - out << state.throughput << " "; - out << state.abort_rate << " "; - out << total_profile_memory << "\n"; - - for (size_t round_id = 0; round_id < state.profile_throughput.size(); - ++round_id) { - out << "[" << std::setw(3) << std::left - << state.profile_duration * round_id << " - " << std::setw(3) - << std::left << state.profile_duration * (round_id + 1) - << " s]: " << state.profile_throughput[round_id] << " " - << state.profile_abort_rate[round_id] << " " - << state.profile_memory[round_id] << "\n"; - } - out.flush(); - out.close(); -} - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton diff --git a/src/main/ycsb/ycsb_loader.cpp b/src/main/ycsb/ycsb_loader.cpp deleted file mode 100644 index 50e2192ba9d..00000000000 --- a/src/main/ycsb/ycsb_loader.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_loader.cpp -// -// Identification: src/main/ycsb/ycsb_loader.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/ycsb/ycsb_loader.h" -#include "benchmark/ycsb/ycsb_configuration.h" -#include "catalog/catalog.h" -#include "catalog/schema.h" -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" -#include "executor/abstract_executor.h" -#include "executor/insert_executor.h" -#include "executor/executor_context.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "index/index_factory.h" -#include "planner/insert_plan.h" -#include "storage/tile.h" -#include "storage/tile_group.h" -#include "storage/data_table.h" -#include "storage/table_factory.h" -#include "storage/database.h" - -// Logging mode -// extern peloton::LoggingType peloton_logging_mode; - -namespace peloton { -namespace benchmark { -namespace ycsb { - -storage::Database *ycsb_database = nullptr; - -storage::DataTable *user_table = nullptr; - -void CreateYCSBDatabase() { - const oid_t col_count = state.column_count + 1; - const bool is_inlined = false; - - ///////////////////////////////////////////////////////// - // Create tables - ///////////////////////////////////////////////////////// - // Clean up - delete ycsb_database; - ycsb_database = nullptr; - user_table = nullptr; - - auto catalog = catalog::Catalog::GetInstance(); - ycsb_database = new storage::Database(ycsb_database_oid); - catalog->AddDatabase(ycsb_database); - - bool own_schema = true; - bool adapt_table = false; - // Create schema first - std::vector columns; - - auto column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "YCSB_KEY", is_inlined); - columns.push_back(column); - - if (state.string_mode == true) { - for (oid_t col_itr = 1; col_itr < col_count; col_itr++) { - auto column = - catalog::Column(type::TypeId::VARCHAR, 100, - "FIELD" + std::to_string(col_itr), is_inlined); - columns.push_back(column); - } - } else { - for (oid_t col_itr = 1; col_itr < col_count; col_itr++) { - auto column = - catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), - "FIELD" + std::to_string(col_itr), is_inlined); - columns.push_back(column); - } - } - - catalog::Schema *table_schema = new catalog::Schema(columns); - std::string table_name("USERTABLE"); - - user_table = storage::TableFactory::GetDataTable( - ycsb_database_oid, user_table_oid, table_schema, table_name, - DEFAULT_TUPLES_PER_TILEGROUP, own_schema, adapt_table); - - ycsb_database->AddTable(user_table); - - // Primary index on user key - std::vector key_attrs; - - auto tuple_schema = user_table->GetSchema(); - catalog::Schema *key_schema; - index::IndexMetadata *index_metadata; - bool unique; - - key_attrs = {0}; - key_schema = catalog::Schema::CopySchema(tuple_schema, key_attrs); - key_schema->SetIndexedColumns(key_attrs); - - unique = true; - - index_metadata = new index::IndexMetadata( - "primary_index", user_table_pkey_index_oid, user_table_oid, - ycsb_database_oid, state.index, IndexConstraintType::PRIMARY_KEY, - tuple_schema, key_schema, key_attrs, unique); - - std::shared_ptr pkey_index( - index::IndexFactory::GetIndex(index_metadata)); - user_table->AddIndex(pkey_index); -} - -void LoadYCSBRows(const int begin_rowid, const int end_rowid) { - const oid_t col_count = state.column_count + 1; - - // Pick the user table - auto table_schema = user_table->GetSchema(); - - ///////////////////////////////////////////////////////// - // Load in the data - ///////////////////////////////////////////////////////// - - std::unique_ptr pool(new type::EphemeralPool()); - - // Insert tuples into tile_group. - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - const bool allocate = true; - auto txn = txn_manager.BeginTransaction(); - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - for (int rowid = begin_rowid; rowid < end_rowid; rowid++) { - std::unique_ptr tuple( - new storage::Tuple(table_schema, allocate)); - - auto primary_key_value = type::ValueFactory::GetIntegerValue(rowid); - tuple->SetValue(0, primary_key_value, nullptr); - - - if (state.string_mode == true) { - auto key_value = type::ValueFactory::GetVarcharValue(std::string(100, 'z')); - for (oid_t col_itr = 1; col_itr < col_count; col_itr++) { - tuple->SetValue(col_itr, key_value, pool.get()); - } - } else { - auto key_value = type::ValueFactory::GetIntegerValue(rowid); - for (oid_t col_itr = 1; col_itr < col_count; col_itr++) { - tuple->SetValue(col_itr, key_value, nullptr); - } - } - - planner::InsertPlan node(user_table, std::move(tuple)); - executor::InsertExecutor executor(&node, context.get()); - executor.Execute(); - } - - txn_manager.CommitTransaction(txn); -} - -void LoadYCSBDatabase() { - - std::chrono::steady_clock::time_point start_time; - start_time = std::chrono::steady_clock::now(); - - const int tuple_count = state.scale_factor * 1000; - int row_per_thread = tuple_count / state.loader_count; - - std::vector> load_threads(state.loader_count); - - for (int thread_id = 0; thread_id < state.loader_count - 1; ++thread_id) { - int begin_rowid = row_per_thread * thread_id; - int end_rowid = row_per_thread * (thread_id + 1); - load_threads[thread_id].reset(new std::thread(LoadYCSBRows, begin_rowid, end_rowid)); - } - - int thread_id = state.loader_count - 1; - int begin_rowid = row_per_thread * thread_id; - int end_rowid = tuple_count; - load_threads[thread_id].reset(new std::thread(LoadYCSBRows, begin_rowid, end_rowid)); - - for (int thread_id = 0; thread_id < state.loader_count; ++thread_id) { - load_threads[thread_id]->join(); - } - - std::chrono::steady_clock::time_point end_time = std::chrono::steady_clock::now(); - double diff = std::chrono::duration_cast(end_time - start_time).count(); - LOG_INFO("database table loading time = %lf ms", diff); - - LOG_INFO("%sTABLE SIZES%s", peloton::GETINFO_HALF_THICK_LINE.c_str(), peloton::GETINFO_HALF_THICK_LINE.c_str()); - LOG_INFO("user count = %lu", user_table->GetTupleCount()); - -} - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton diff --git a/src/main/ycsb/ycsb_mixed.cpp b/src/main/ycsb/ycsb_mixed.cpp deleted file mode 100644 index 769b630f6cf..00000000000 --- a/src/main/ycsb/ycsb_mixed.cpp +++ /dev/null @@ -1,231 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_mixed.cpp -// -// Identification: src/main/ycsb/ycsb_mixed.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benchmark/ycsb/ycsb_configuration.h" -#include "benchmark/ycsb/ycsb_loader.h" -#include "benchmark/ycsb/ycsb_workload.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/generator.h" -#include "common/internal_types.h" -#include "common/logger.h" -#include "common/timer.h" -#include "type/value.h" -#include "type/value_factory.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/abstract_executor.h" -#include "executor/executor_context.h" -#include "executor/index_scan_executor.h" -#include "executor/insert_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/update_executor.h" - -#include "common/container_tuple.h" -#include "expression/abstract_expression.h" -#include "expression/comparison_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/expression_util.h" -#include "expression/tuple_value_expression.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/index_scan_plan.h" -#include "planner/insert_plan.h" -#include "planner/materialization_plan.h" -#include "planner/update_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace ycsb { - -bool RunMixed(const size_t thread_id, ZipfDistribution &zipf, FastRandom &rng) { - auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); - - concurrency::TransactionContext *txn = - txn_manager.BeginTransaction(thread_id); - - std::unique_ptr context( - new executor::ExecutorContext(txn)); - - // Column ids to be added to logical tile. - std::vector column_ids; - oid_t column_count = state.column_count + 1; - - // read all the attributes in a tuple. - for (oid_t col_itr = 0; col_itr < column_count; col_itr++) { - column_ids.push_back(col_itr); - } - - // Create and set up index scan executor - std::vector key_column_ids; - std::vector expr_types; - - key_column_ids.push_back(0); - expr_types.push_back(ExpressionType::COMPARE_EQUAL); - - std::vector runtime_keys; - - for (int i = 0; i < state.operation_count; i++) { - auto rng_val = rng.NextUniform(); - - if (rng_val < state.update_ratio) { - ///////////////////////////////////////////////////////// - // PERFORM UPDATE - ///////////////////////////////////////////////////////// - - // set up parameter values - std::vector values; - - auto lookup_key = zipf.GetNextNumber(); - - values.push_back(type::ValueFactory::GetIntegerValue(lookup_key).Copy()); - - planner::IndexScanPlan::IndexScanDesc index_scan_desc( - user_table_pkey_index_oid, key_column_ids, expr_types, values, - runtime_keys); - - // Create plan node. - auto predicate = nullptr; - - planner::IndexScanPlan index_scan_node(user_table, predicate, column_ids, - index_scan_desc); - - // Run the executor - executor::IndexScanExecutor index_scan_executor(&index_scan_node, - context.get()); - - TargetList target_list; - DirectMapList direct_map_list; - - // update multiple attributes - for (oid_t col_itr = 0; col_itr < column_count; col_itr++) { - if (col_itr == 1) { - if (state.string_mode == true) { - std::string update_raw_value(100, 'a'); - type::Value update_val = - type::ValueFactory::GetVarcharValue(update_raw_value).Copy(); - - planner::DerivedAttribute attr{ - expression::ExpressionUtil::ConstantValueFactory(update_val)}; - target_list.emplace_back(col_itr, attr); - - } else { - int update_raw_value = 1; - type::Value update_val = - type::ValueFactory::GetIntegerValue(update_raw_value).Copy(); - - planner::DerivedAttribute attr{ - expression::ExpressionUtil::ConstantValueFactory(update_val)}; - target_list.emplace_back(col_itr, attr); - } - } else { - direct_map_list.emplace_back(col_itr, - std::pair(0, col_itr)); - } - } - - std::unique_ptr project_info( - new planner::ProjectInfo(std::move(target_list), - std::move(direct_map_list))); - planner::UpdatePlan update_node(user_table, std::move(project_info)); - - executor::UpdateExecutor update_executor(&update_node, context.get()); - - update_executor.AddChild(&index_scan_executor); - - ExecuteUpdate(&update_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - - } else { - ///////////////////////////////////////////////////////// - // PERFORM READ - ///////////////////////////////////////////////////////// - - // set up parameter values - std::vector values; - - auto lookup_key = zipf.GetNextNumber(); - - values.push_back(type::ValueFactory::GetIntegerValue(lookup_key).Copy()); - - planner::IndexScanPlan::IndexScanDesc index_scan_desc( - user_table_pkey_index_oid, key_column_ids, expr_types, values, - runtime_keys); - - // Create plan node. - auto predicate = nullptr; - - planner::IndexScanPlan index_scan_node(user_table, predicate, column_ids, - index_scan_desc); - - // Run the executor - executor::IndexScanExecutor index_scan_executor(&index_scan_node, - context.get()); - - ExecuteRead(&index_scan_executor); - - if (txn->GetResult() != ResultType::SUCCESS) { - txn_manager.AbortTransaction(txn); - return false; - } - } - } - - // transaction passed execution. - PELOTON_ASSERT(txn->GetResult() == ResultType::SUCCESS); - - auto result = txn_manager.CommitTransaction(txn); - - if (result == ResultType::SUCCESS) { - return true; - - } else { - // transaction failed commitment. - PELOTON_ASSERT(result == ResultType::ABORTED || - result == ResultType::FAILURE); - return false; - } -} -} -} -} diff --git a/src/main/ycsb/ycsb_workload.cpp b/src/main/ycsb/ycsb_workload.cpp deleted file mode 100644 index 994f1fbf10c..00000000000 --- a/src/main/ycsb/ycsb_workload.cpp +++ /dev/null @@ -1,321 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Peloton -// -// ycsb_workload.cpp -// -// Identification: src/main/ycsb/ycsb_workload.cpp -// -// Copyright (c) 2015-16, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "storage/storage_manager.h" - -#include "benchmark/ycsb/ycsb_workload.h" -#include "benchmark/ycsb/ycsb_configuration.h" -#include "benchmark/ycsb/ycsb_loader.h" - -#include "catalog/manager.h" -#include "catalog/schema.h" - -#include "common/internal_types.h" -#include "type/value.h" -#include "type/value_factory.h" -#include "common/logger.h" -#include "common/timer.h" -#include "common/generator.h" -#include "common/platform.h" -#include "common/container_tuple.h" - -#include "concurrency/transaction_context.h" -#include "concurrency/transaction_manager_factory.h" - -#include "executor/executor_context.h" -#include "executor/abstract_executor.h" -#include "executor/logical_tile.h" -#include "executor/logical_tile_factory.h" -#include "executor/materialization_executor.h" -#include "executor/update_executor.h" -#include "executor/index_scan_executor.h" - -#include "expression/abstract_expression.h" -#include "expression/constant_value_expression.h" -#include "expression/tuple_value_expression.h" -#include "expression/comparison_expression.h" -#include "expression/expression_util.h" - -#include "index/index_factory.h" - -#include "logging/log_manager.h" - -#include "planner/abstract_plan.h" -#include "planner/materialization_plan.h" -#include "planner/insert_plan.h" -#include "planner/update_plan.h" -#include "planner/index_scan_plan.h" - -#include "storage/data_table.h" -#include "storage/table_factory.h" - -namespace peloton { -namespace benchmark { -namespace ycsb { - - -///////////////////////////////////////////////////////// -// WORKLOAD -///////////////////////////////////////////////////////// - -volatile bool is_running = true; - -PadInt *abort_counts; -PadInt *commit_counts; - -#ifndef __APPLE__ -void PinToCore(size_t core) { - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(core, &cpuset); - pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); -#else -void PinToCore(size_t UNUSED_ATTRIBUTE core) { -// Mac OS X does not export interfaces that identify processors or control thread placement -// explicit thread to processor binding is not supported. -// Reference: https://superuser.com/questions/149312/how-to-set-processor-affinity-on-os-x -#endif -} - -void RunBackend(const size_t thread_id) { - - PinToCore(thread_id); - - PadInt &execution_count_ref = abort_counts[thread_id]; - PadInt &transaction_count_ref = commit_counts[thread_id]; - - ZipfDistribution zipf((state.scale_factor * 1000) - 1, - state.zipf_theta); - - FastRandom rng(rand()); - - // backoff - uint32_t backoff_shifts = 0; - - while (true) { - if (is_running == false) { - break; - } - while (RunMixed(thread_id, zipf, rng) == false) { - if (is_running == false) { - break; - } - execution_count_ref.data++; - // backoff - if (state.exp_backoff) { - if (backoff_shifts < 13) { - ++backoff_shifts; - } - uint64_t sleep_duration = 1UL << backoff_shifts; - sleep_duration *= 100; - std::this_thread::sleep_for(std::chrono::microseconds(sleep_duration)); - } - } - backoff_shifts >>= 1; - transaction_count_ref.data++; - } -} - -void RunWorkload() { - // Execute the workload to build the log - std::vector thread_group; - size_t num_threads = state.backend_count; - - abort_counts = new PadInt[num_threads]; - PELOTON_MEMSET(abort_counts, 0, sizeof(PadInt) * num_threads); - - commit_counts = new PadInt[num_threads]; - PELOTON_MEMSET(commit_counts, 0, sizeof(PadInt) * num_threads); - - size_t profile_round = (size_t)(state.duration / state.profile_duration); - - PadInt **abort_counts_profiles = new PadInt *[profile_round]; - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - abort_counts_profiles[round_id] = new PadInt[num_threads]; - } - - PadInt **commit_counts_profiles = new PadInt *[profile_round]; - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - commit_counts_profiles[round_id] = new PadInt[num_threads]; - } - - // Launch a group of threads - for (size_t thread_itr = 0; thread_itr < num_threads; ++thread_itr) { - thread_group.push_back(std::thread(RunBackend, thread_itr)); - } - - ////////////////////////////////////// - oid_t last_tile_group_id = 0; - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - std::this_thread::sleep_for( - std::chrono::milliseconds(int(state.profile_duration * 1000))); - PELOTON_MEMCPY(abort_counts_profiles[round_id], abort_counts, - sizeof(PadInt) * num_threads); - PELOTON_MEMCPY(commit_counts_profiles[round_id], commit_counts, - sizeof(PadInt) * num_threads); - - storage::StorageManager *storage_manager = storage::StorageManager::GetInstance(); - oid_t current_tile_group_id = storage_manager->GetCurrentTileGroupId(); - if (round_id != 0) { - state.profile_memory.push_back(current_tile_group_id - last_tile_group_id); - } - last_tile_group_id = current_tile_group_id; - - } - - state.profile_memory.push_back(state.profile_memory.at(state.profile_memory.size() - 1)); - - is_running = false; - - // Join the threads with the main thread - for (size_t thread_itr = 0; thread_itr < num_threads; ++thread_itr) { - thread_group[thread_itr].join(); - } - - // calculate the throughput and abort rate for the first round. - uint64_t total_commit_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_commit_count += commit_counts_profiles[0][i].data; - } - - uint64_t total_abort_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_abort_count += abort_counts_profiles[0][i].data; - } - - state.profile_throughput.push_back(total_commit_count * 1.0 / - state.profile_duration); - state.profile_abort_rate.push_back(total_abort_count * 1.0 / - total_commit_count); - - // calculate the throughput and abort rate for the remaining rounds. - for (size_t round_id = 0; round_id < profile_round - 1; ++round_id) { - total_commit_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_commit_count += commit_counts_profiles[round_id + 1][i].data - - commit_counts_profiles[round_id][i].data; - } - - total_abort_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_abort_count += abort_counts_profiles[round_id + 1][i].data - - abort_counts_profiles[round_id][i].data; - } - - state.profile_throughput.push_back(total_commit_count * 1.0 / - state.profile_duration); - state.profile_abort_rate.push_back(total_abort_count * 1.0 / - total_commit_count); - } - - ////////////////////////////////////////////////// - // calculate the aggregated throughput and abort rate. - total_commit_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_commit_count += commit_counts_profiles[profile_round - 1][i].data; - } - - total_abort_count = 0; - for (size_t i = 0; i < num_threads; ++i) { - total_abort_count += abort_counts_profiles[profile_round - 1][i].data; - } - - state.throughput = total_commit_count * 1.0 / state.duration; - state.abort_rate = total_abort_count * 1.0 / total_commit_count; - - ////////////////////////////////////////////////// - - // cleanup everything. - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - delete[] abort_counts_profiles[round_id]; - abort_counts_profiles[round_id] = nullptr; - } - - for (size_t round_id = 0; round_id < profile_round; ++round_id) { - delete[] commit_counts_profiles[round_id]; - commit_counts_profiles[round_id] = nullptr; - } - - delete[] abort_counts_profiles; - abort_counts_profiles = nullptr; - delete[] commit_counts_profiles; - commit_counts_profiles = nullptr; - - delete[] abort_counts; - abort_counts = nullptr; - delete[] commit_counts; - commit_counts = nullptr; - -} - - -///////////////////////////////////////////////////////// -// HARNESS -///////////////////////////////////////////////////////// - -std::vector> ExecuteRead(executor::AbstractExecutor* executor) { - executor->Init(); - - std::vector> logical_tile_values; - - // Execute stuff - while (executor->Execute() == true) { - std::unique_ptr result_tile(executor->GetOutput()); - - if(result_tile == nullptr) { - break; - } - - auto column_count = result_tile->GetColumnCount(); - LOG_TRACE("result column count = %d\n", (int)column_count); - - for (oid_t tuple_id : *result_tile) { - ContainerTuple cur_tuple(result_tile.get(), - tuple_id); - std::vector tuple_values; - for (oid_t column_itr = 0; column_itr < column_count; column_itr++){ - auto value = cur_tuple.GetValue(column_itr); - tuple_values.push_back(value); - } - - // Move the tuple list - logical_tile_values.push_back(std::move(tuple_values)); - } - } - - return logical_tile_values; -} - -void ExecuteUpdate(executor::AbstractExecutor* executor) { - executor->Init(); - // Execute stuff - while (executor->Execute() == true); -} - - - -} // namespace ycsb -} // namespace benchmark -} // namespace peloton