void StatsTestsUtil::CreateTable(bool has_primary_key) { LOG_INFO("Creating a table..."); auto id_column = catalog::Column( common::Type::INTEGER, common::Type::GetTypeSize(common::Type::INTEGER), "dept_id", true); if (has_primary_key) { catalog::Constraint constraint(CONSTRAINT_TYPE_PRIMARY, "con_primary"); id_column.AddConstraint(constraint); } auto name_column = catalog::Column(common::Type::VARCHAR, 32, "dept_name", false); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); planner::CreatePlan node("department_table", "emp_db", std::move(table_schema), CreateType::CREATE_TYPE_TABLE); executor::CreateExecutor create_executor(&node, context.get()); create_executor.Init(); create_executor.Execute(); txn_manager.CommitTransaction(txn); }
TEST_F(CreateTests, CreatingTable) { catalog::Bootstrapper::bootstrap(); // Insert a table first auto id_column = catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER), "dept_id", true); auto name_column = catalog::Column(VALUE_TYPE_VARCHAR, 32, "dept_name", false); std::unique_ptr<catalog::Schema> table_schema(new catalog::Schema({id_column, name_column})); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); planner::CreatePlan node("department_table", std::move(table_schema)); executor::CreateExecutor executor(&node, context.get()); executor.Init(); executor.Execute(); txn_manager.CommitTransaction(); EXPECT_EQ(catalog::Bootstrapper::global_catalog->GetDatabaseWithName("default_database")->GetTableCount(), 1); }
TEST_F(CatalogTests, CreatingTable) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); auto id_column = catalog::Column( type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "id", true); id_column.AddConstraint( catalog::Constraint(ConstraintType::PRIMARY, "primary_key")); auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_2( new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_3( new catalog::Schema({id_column, name_column})); catalog::Catalog::GetInstance()->CreateTable( "emp_db", DEFAULT_SCHEMA_NAME, "emp_table", std::move(table_schema), txn); catalog::Catalog::GetInstance()->CreateTable("emp_db", DEFAULT_SCHEMA_NAME, "department_table", std::move(table_schema_2), txn); catalog::Catalog::GetInstance()->CreateTable("emp_db", DEFAULT_SCHEMA_NAME, "salary_table", std::move(table_schema_3), txn); // insert random tuple into DATABASE_METRICS_CATALOG and check std::unique_ptr<type::AbstractPool> pool(new type::EphemeralPool()); catalog::DatabaseMetricsCatalog::GetInstance()->InsertDatabaseMetrics( 2, 3, 4, 5, pool.get(), txn); // inset meaningless tuple into QUERY_METRICS_CATALOG and check stats::QueryMetric::QueryParamBuf param; param.len = 1; param.buf = (unsigned char *)pool->Allocate(1); *param.buf = 'a'; auto database_object = catalog::Catalog::GetInstance()->GetDatabaseObject("emp_db", txn); catalog::Catalog::GetInstance() ->GetSystemCatalogs(database_object->GetDatabaseOid()) ->GetQueryMetricsCatalog() ->InsertQueryMetrics("a query", database_object->GetDatabaseOid(), 1, param, param, param, 1, 1, 1, 1, 1, 1, 1, pool.get(), txn); auto param1 = catalog::Catalog::GetInstance() ->GetSystemCatalogs(database_object->GetDatabaseOid()) ->GetQueryMetricsCatalog() ->GetParamTypes("a query", txn); EXPECT_EQ(1, param1.len); EXPECT_EQ('a', *param1.buf); // check colum object EXPECT_EQ("name", catalog::Catalog::GetInstance() ->GetTableObject("emp_db", DEFAULT_SCHEMA_NAME, "department_table", txn) ->GetColumnObject(1) ->GetColumnName()); txn_manager.CommitTransaction(txn); }
TEST_F(CreateTests, CreatingTable) { // Bootstrap catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, nullptr); // Insert a table first auto id_column = catalog::Column( common::Type::INTEGER, common::Type::GetTypeSize(common::Type::INTEGER), "dept_id", true); auto name_column = catalog::Column(common::Type::VARCHAR, 32, "dept_name", false); // Schema std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); // Create plans planner::CreatePlan node("department_table", DEFAULT_DB_NAME, std::move(table_schema), CreateType::CREATE_TYPE_TABLE); // Create executer executor::CreateExecutor executor(&node, context.get()); executor.Init(); executor.Execute(); txn_manager.CommitTransaction(txn); EXPECT_EQ(catalog::Catalog::GetInstance() ->GetDatabaseWithName(DEFAULT_DB_NAME) ->GetTableCount(), 1); // free the database just created txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn); txn_manager.CommitTransaction(txn); }
TEST_F(CatalogTests, CreatingTable) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); auto id_column = catalog::Column( common::Type::INTEGER, common::Type::GetTypeSize(common::Type::INTEGER), "id", true); auto name_column = catalog::Column(common::Type::VARCHAR, 32, "name", true); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_2( new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_3( new catalog::Schema({id_column, name_column})); catalog::Catalog::GetInstance()->CreateTable("EMP_DB", "emp_table", std::move(table_schema), txn); catalog::Catalog::GetInstance()->CreateTable("EMP_DB", "department_table", std::move(table_schema_2), txn); catalog::Catalog::GetInstance()->CreateTable("EMP_DB", "salary_table", std::move(table_schema_3), txn); txn_manager.CommitTransaction(txn); EXPECT_EQ(catalog::Catalog::GetInstance() ->GetDatabaseWithName("EMP_DB") ->GetTableWithName("department_table") ->GetSchema() ->GetColumn(1) .GetName(), "name"); EXPECT_EQ(catalog::Catalog::GetInstance() ->GetDatabaseWithName("catalog_db") ->GetTableWithName("table_catalog") ->GetTupleCount(), 3); EXPECT_EQ(catalog::Catalog::GetInstance() ->GetDatabaseWithName("catalog_db") ->GetTableWithName("table_catalog") ->GetSchema() ->GetLength(), 72); }
TEST_F(CatalogTests, CreatingTable) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); txn_manager.BeginTransaction(); auto id_column = catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER), "dept_id", true); auto name_column = catalog::Column(VALUE_TYPE_VARCHAR, 32, "dept_name", true); std::unique_ptr<catalog::Schema> table_schema(new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_2(new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_3(new catalog::Schema({id_column, name_column})); catalog::Bootstrapper::global_catalog->CreateTable("EMP_DB", "emp_table", std::move(table_schema)); catalog::Bootstrapper::global_catalog->CreateTable("EMP_DB", "department_table", std::move(table_schema_2)); catalog::Bootstrapper::global_catalog->CreateTable("EMP_DB", "salary_table", std::move(table_schema_3)); txn_manager.CommitTransaction(); EXPECT_EQ(catalog::Bootstrapper::global_catalog->GetDatabaseWithName("EMP_DB")->GetTableWithName("department_table")->GetSchema()->GetColumn(1).GetName(), "dept_name"); EXPECT_EQ(catalog::Bootstrapper::global_catalog->GetDatabaseWithName("catalog_db")->GetTableWithName("table_catalog")->GetNumberOfTuples(), 3); }
TEST_F(DropTests, DroppingTable) { catalog::Bootstrapper::bootstrap(); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); txn_manager.BeginTransaction(); // Insert a table first auto id_column = catalog::Column(VALUE_TYPE_INTEGER, GetTypeSize(VALUE_TYPE_INTEGER), "dept_id", true); auto name_column = catalog::Column(VALUE_TYPE_VARCHAR, 32, "dept_name", false); std::unique_ptr<catalog::Schema> table_schema(new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema2(new catalog::Schema({id_column, name_column})); catalog::Bootstrapper::global_catalog->CreateDatabase("default_database"); txn_manager.CommitTransaction(); txn_manager.BeginTransaction(); catalog::Bootstrapper::global_catalog->CreateTable("default_database", "department_table", std::move(table_schema)); txn_manager.CommitTransaction(); txn_manager.BeginTransaction(); catalog::Bootstrapper::global_catalog->CreateTable("default_database", "department_table_2", std::move(table_schema2)); txn_manager.CommitTransaction(); EXPECT_EQ(catalog::Bootstrapper::global_catalog->GetDatabaseWithName("default_database")->GetTableCount(), 2); // Now dropping the table using the executer txn_manager.BeginTransaction(); catalog::Bootstrapper::global_catalog->DropTable("default_database", "department_table"); txn_manager.CommitTransaction(); EXPECT_EQ(catalog::Bootstrapper::global_catalog->GetDatabaseWithName("default_database")->GetTableCount(), 1); }
TEST_F(InsertTests, InsertRecord) { catalog::Catalog::GetInstance(); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); // Insert a table first auto id_column = catalog::Column( common::Type::INTEGER, common::Type::GetTypeSize(common::Type::INTEGER), "dept_id", true); auto name_column = catalog::Column(common::Type::VARCHAR, 32, "dept_name", false); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn); txn_manager.CommitTransaction(txn); txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->CreateTable(DEFAULT_DB_NAME, "TEST_TABLE", std::move(table_schema), txn); txn_manager.CommitTransaction(txn); txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); std::unique_ptr<parser::InsertStatement> insert_node( new parser::InsertStatement(INSERT_TYPE_VALUES)); char *name = new char[11](); strcpy(name, "TEST_TABLE"); expression::ParserExpression *table_name = new expression::ParserExpression( EXPRESSION_TYPE_TABLE_REF, name, nullptr); char *col_1 = new char[8](); strcpy(col_1, "dept_id"); char *col_2 = new char[10](); strcpy(col_2, "dept_name"); insert_node->table_name = table_name; insert_node->columns = new std::vector<char *>; insert_node->columns->push_back(const_cast<char *>(col_1)); insert_node->columns->push_back(const_cast<char *>(col_2)); insert_node->values = new std::vector<expression::AbstractExpression *>; insert_node->values->push_back(new expression::ConstantValueExpression( common::ValueFactory::GetIntegerValue(70))); insert_node->values->push_back(new expression::ConstantValueExpression( common::ValueFactory::GetVarcharValue("Hello"))); insert_node->select = new parser::SelectStatement(); planner::InsertPlan node(insert_node.get()); executor::InsertExecutor executor(&node, context.get()); EXPECT_TRUE(executor.Init()); EXPECT_TRUE(executor.Execute()); txn_manager.CommitTransaction(txn); // free the database just created txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn); txn_manager.CommitTransaction(txn); }
TEST_F(DeleteTests, VariousOperations) { LOG_INFO("Bootstrapping..."); catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, nullptr); LOG_INFO("Bootstrapping completed!"); // Create a table first LOG_INFO("Creating a table..."); auto id_column = catalog::Column( common::Type::INTEGER, common::Type::GetTypeSize(common::Type::INTEGER), "dept_id", true); auto name_column = catalog::Column(common::Type::VARCHAR, 32, "dept_name", false); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); auto& txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); planner::CreatePlan node("department_table", DEFAULT_DB_NAME, std::move(table_schema), CreateType::CREATE_TYPE_TABLE); executor::CreateExecutor create_executor(&node, context.get()); create_executor.Init(); create_executor.Execute(); txn_manager.CommitTransaction(txn); EXPECT_EQ(catalog::Catalog::GetInstance() ->GetDatabaseWithName(DEFAULT_DB_NAME) ->GetTableCount(), 1); LOG_INFO("Table created!"); // Inserting a tuple end-to-end LOG_INFO("Inserting a tuple..."); LOG_INFO( "Query: INSERT INTO department_table(dept_id,dept_name) VALUES " "(1,'hello_1');"); std::unique_ptr<Statement> statement; statement.reset(new Statement( "INSERT", "INSERT INTO department_table(dept_id,dept_name) VALUES (1,'hello_1');")); auto& peloton_parser = parser::Parser::GetInstance(); LOG_INFO("Building parse tree..."); auto insert_stmt = peloton_parser.BuildParseTree( "INSERT INTO department_table(dept_id,dept_name) VALUES (1,'hello_1');"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree( optimizer::SimpleOptimizer::BuildPelotonPlanTree(insert_stmt)); LOG_INFO("Building plan tree completed!"); std::vector<common::Value*> params; std::vector<ResultType> result; bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan"); LOG_INFO("Executing plan..."); std::vector<int> result_format; result_format = std::move(std::vector<int>(0, 0)); bridge::peloton_status status = bridge::PlanExecutor::ExecutePlan( statement->GetPlanTree().get(), params, result, result_format); LOG_INFO("Statement executed. Result: %d", status.m_result); LOG_INFO("Tuple inserted!"); ShowTable(DEFAULT_DB_NAME, "department_table"); LOG_INFO("Inserting a tuple..."); LOG_INFO( "Query: INSERT INTO department_table(dept_id,dept_name) VALUES " "(2,'hello_2');"); statement.reset(new Statement( "INSERT", "INSERT INTO department_table(dept_id,dept_name) VALUES (2,'hello_2');")); LOG_INFO("Building parse tree..."); insert_stmt = peloton_parser.BuildParseTree( "INSERT INTO department_table(dept_id,dept_name) VALUES (2,'hello_2');"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree( optimizer::SimpleOptimizer::BuildPelotonPlanTree(insert_stmt)); LOG_INFO("Building plan tree completed!"); bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan"); LOG_INFO("Executing plan..."); result_format = std::move(std::vector<int>(0, 0)); status = bridge::PlanExecutor::ExecutePlan(statement->GetPlanTree().get(), params, result, result_format); LOG_INFO("Statement executed. Result: %d", status.m_result); LOG_INFO("Tuple inserted!"); ShowTable(DEFAULT_DB_NAME, "department_table"); LOG_INFO("Inserting a tuple..."); LOG_INFO( "Query: INSERT INTO department_table(dept_id,dept_name) VALUES " "(3,'hello_2');"); statement.reset(new Statement( "INSERT", "INSERT INTO department_table(dept_id,dept_name) VALUES (3,'hello_2');")); LOG_INFO("Building parse tree..."); insert_stmt = peloton_parser.BuildParseTree( "INSERT INTO department_table(dept_id,dept_name) VALUES (3,'hello_2');"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree( optimizer::SimpleOptimizer::BuildPelotonPlanTree(insert_stmt)); LOG_INFO("Building plan tree completed!"); bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan"); LOG_INFO("Executing plan..."); result_format = std::move(std::vector<int>(0, 0)); status = bridge::PlanExecutor::ExecutePlan(statement->GetPlanTree().get(), params, result, result_format); LOG_INFO("Statement executed. Result: %d", status.m_result); LOG_INFO("Tuple inserted!"); ShowTable(DEFAULT_DB_NAME, "department_table"); // Just Counting number of tuples in table LOG_INFO("Selecting MAX(dept_id)"); LOG_INFO("Query: SELECT MAX(dept_id) FROM department_table;"); statement.reset( new Statement("MAX", "SELECT MAX(dept_id) FROM department_table;")); LOG_INFO("Building parse tree..."); auto select_stmt = peloton_parser.BuildParseTree( "SELECT MAX(dept_id) FROM department_table;"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree( optimizer::SimpleOptimizer::BuildPelotonPlanTree(select_stmt)); LOG_INFO("Building plan tree completed!"); bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan"); LOG_INFO("Executing plan..."); auto tuple_descriptor = tcop::TrafficCop::GetInstance().GenerateTupleDescriptor( statement->GetQueryString()); result_format = std::move(std::vector<int>(tuple_descriptor.size(), 0)); status = bridge::PlanExecutor::ExecutePlan(statement->GetPlanTree().get(), params, result, result_format); LOG_INFO("Statement executed. Result: %d", status.m_result); LOG_INFO("Counted Tuples!"); // Now deleting end-to-end LOG_INFO("Deleting a tuple..."); LOG_INFO("Query: DELETE FROM department_table"); statement.reset(new Statement("DELETE", "DELETE FROM department_table")); LOG_INFO("Building parse tree..."); auto delete_stmt = peloton_parser.BuildParseTree("DELETE FROM department_table"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree( optimizer::SimpleOptimizer::BuildPelotonPlanTree(delete_stmt)); LOG_INFO("Building plan tree completed!"); bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan"); LOG_INFO("Executing plan..."); result_format = std::move(std::vector<int>(0, 0)); status = bridge::PlanExecutor::ExecutePlan(statement->GetPlanTree().get(), params, result, result_format); LOG_INFO("Statement executed. Result: %d", status.m_result); LOG_INFO("Tuple deleted!"); ShowTable(DEFAULT_DB_NAME, "department_table"); // Test Another delete. Should not find any tuple to be deleted LOG_INFO("Deleting a tuple..."); LOG_INFO("Query: DELETE FROM department_table WHERE dept_id < 2"); statement.reset(new Statement( "DELETE", "DELETE FROM department_table WHERE dept_id < 2")); LOG_INFO("Building parse tree..."); auto delete_stmt_2 = peloton_parser.BuildParseTree( "DELETE FROM department_table WHERE dept_id < 2"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree( optimizer::SimpleOptimizer::BuildPelotonPlanTree(delete_stmt_2)); LOG_INFO("Building plan tree completed!"); bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan"); LOG_INFO("Executing plan..."); result_format = std::move(std::vector<int>(0, 0)); status = bridge::PlanExecutor::ExecutePlan(statement->GetPlanTree().get(), params, result, result_format); LOG_INFO("Statement executed. Result: %d", status.m_result); LOG_INFO("Tuple deleted!"); ShowTable(DEFAULT_DB_NAME, "department_table"); // free the database just created txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn); txn_manager.CommitTransaction(txn); }
TEST_F(DeleteTests, VariousOperations) { LOG_INFO("Bootstrapping..."); auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->CreateDatabase(DEFAULT_DB_NAME, txn); LOG_INFO("Bootstrapping completed!"); // optimizer::SimpleOptimizer optimizer; std::unique_ptr<optimizer::AbstractOptimizer> optimizer; optimizer.reset(new optimizer::Optimizer); auto &traffic_cop = tcop::TrafficCop::GetInstance(); traffic_cop.SetTaskCallback(TestingSQLUtil::UtilTestTaskCallback, &TestingSQLUtil::counter_); // Create a table first LOG_INFO("Creating a table..."); auto id_column = catalog::Column( type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "dept_id", true); auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "dept_name", false); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); planner::CreatePlan node("department_table", DEFUALT_SCHEMA_NAME, DEFAULT_DB_NAME, std::move(table_schema), CreateType::TABLE); executor::CreateExecutor create_executor(&node, context.get()); create_executor.Init(); create_executor.Execute(); LOG_INFO("Table created!"); storage::DataTable *table = catalog::Catalog::GetInstance()->GetTableWithName( DEFAULT_DB_NAME, DEFUALT_SCHEMA_NAME, "department_table", txn); txn_manager.CommitTransaction(txn); txn = txn_manager.BeginTransaction(); traffic_cop.SetTcopTxnState(txn); // Inserting a tuple end-to-end LOG_INFO("Inserting a tuple..."); LOG_INFO( "Query: INSERT INTO department_table(dept_id,dept_name) VALUES " "(1,'hello_1');"); std::unique_ptr<Statement> statement; statement.reset(new Statement( "INSERT", "INSERT INTO department_table(dept_id,dept_name) VALUES (1,'hello_1');")); auto &peloton_parser = parser::PostgresParser::GetInstance(); LOG_INFO("Building parse tree..."); auto insert_stmt = peloton_parser.BuildParseTree( "INSERT INTO department_table(dept_id,dept_name) VALUES (1,'hello_1');"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Binding parse tree..."); auto parse_tree = insert_stmt->GetStatement(0); auto bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME); bind_node_visitor.BindNameToNode(parse_tree); LOG_INFO("Binding parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree(optimizer->BuildPelotonPlanTree(insert_stmt, txn)); LOG_INFO("Building plan tree completed!"); std::vector<type::Value> params; std::vector<ResultValue> result; LOG_INFO("Executing plan...\n%s", planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str()); std::vector<int> result_format; result_format = std::vector<int>(0, 0); TestingSQLUtil::counter_.store(1); executor::ExecutionResult status = traffic_cop.ExecuteHelper( statement->GetPlanTree(), params, result, result_format); if (traffic_cop.GetQueuing()) { TestingSQLUtil::ContinueAfterComplete(); traffic_cop.ExecuteStatementPlanGetResult(); status = traffic_cop.p_status_; traffic_cop.SetQueuing(false); } LOG_INFO("Statement executed. Result: %s", ResultTypeToString(status.m_result).c_str()); LOG_INFO("Tuple inserted!"); traffic_cop.CommitQueryHelper(); ShowTable(DEFAULT_DB_NAME, "department_table"); txn = txn_manager.BeginTransaction(); traffic_cop.SetTcopTxnState(txn); LOG_INFO("Inserting a tuple..."); LOG_INFO( "Query: INSERT INTO department_table(dept_id,dept_name) VALUES " "(2,'hello_2');"); statement.reset(new Statement( "INSERT", "INSERT INTO department_table(dept_id,dept_name) VALUES (2,'hello_2');")); LOG_INFO("Building parse tree..."); insert_stmt = peloton_parser.BuildParseTree( "INSERT INTO department_table(dept_id,dept_name) VALUES (2,'hello_2');"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Binding parse tree..."); parse_tree = insert_stmt->GetStatement(0); bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME); bind_node_visitor.BindNameToNode(parse_tree); LOG_INFO("Binding parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree(optimizer->BuildPelotonPlanTree(insert_stmt, txn)); LOG_INFO("Building plan tree completed!\n%s", planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str()); LOG_INFO("Executing plan..."); result_format = std::vector<int>(0, 0); TestingSQLUtil::counter_.store(1); status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result, result_format); if (traffic_cop.GetQueuing()) { TestingSQLUtil::ContinueAfterComplete(); traffic_cop.ExecuteStatementPlanGetResult(); status = traffic_cop.p_status_; traffic_cop.SetQueuing(false); } LOG_INFO("Statement executed. Result: %s", ResultTypeToString(status.m_result).c_str()); LOG_INFO("Tuple inserted!"); traffic_cop.CommitQueryHelper(); ShowTable(DEFAULT_DB_NAME, "department_table"); txn = txn_manager.BeginTransaction(); traffic_cop.SetTcopTxnState(txn); LOG_INFO("Inserting a tuple..."); LOG_INFO( "Query: INSERT INTO department_table(dept_id,dept_name) VALUES " "(3,'hello_2');"); statement.reset(new Statement( "INSERT", "INSERT INTO department_table(dept_id,dept_name) VALUES (3,'hello_2');")); LOG_INFO("Building parse tree..."); insert_stmt = peloton_parser.BuildParseTree( "INSERT INTO department_table(dept_id,dept_name) VALUES (3,'hello_2');"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Binding parse tree..."); parse_tree = insert_stmt->GetStatement(0); bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME); bind_node_visitor.BindNameToNode(parse_tree); LOG_INFO("Binding parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree(optimizer->BuildPelotonPlanTree(insert_stmt, txn)); LOG_INFO("Building plan tree completed!\n%s", planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str()); LOG_INFO("Executing plan..."); result_format = std::vector<int>(0, 0); TestingSQLUtil::counter_.store(1); status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result, result_format); if (traffic_cop.GetQueuing()) { TestingSQLUtil::ContinueAfterComplete(); traffic_cop.ExecuteStatementPlanGetResult(); status = traffic_cop.p_status_; traffic_cop.SetQueuing(false); } LOG_INFO("Statement executed. Result: %s", ResultTypeToString(status.m_result).c_str()); LOG_INFO("Tuple inserted!"); traffic_cop.CommitQueryHelper(); ShowTable(DEFAULT_DB_NAME, "department_table"); LOG_INFO("%s", table->GetInfo().c_str()); txn = txn_manager.BeginTransaction(); traffic_cop.SetTcopTxnState(txn); // Just Counting number of tuples in table LOG_INFO("Selecting MAX(dept_id)"); LOG_INFO("Query: SELECT MAX(dept_id) FROM department_table;"); statement.reset( new Statement("MAX", "SELECT MAX(dept_id) FROM department_table;")); LOG_INFO("Building parse tree..."); auto select_stmt = peloton_parser.BuildParseTree( "SELECT MAX(dept_id) FROM department_table;"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Binding parse tree..."); parse_tree = select_stmt->GetStatement(0); bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME); bind_node_visitor.BindNameToNode(parse_tree); LOG_INFO("Binding parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree(optimizer->BuildPelotonPlanTree(select_stmt, txn)); LOG_INFO("Building plan tree completed!\n%s", planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str()); LOG_INFO("Executing plan..."); auto tuple_descriptor = traffic_cop.GenerateTupleDescriptor(select_stmt->GetStatement(0)); result_format = std::vector<int>(tuple_descriptor.size(), 0); TestingSQLUtil::counter_.store(1); status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result, result_format); if (traffic_cop.GetQueuing()) { TestingSQLUtil::ContinueAfterComplete(); traffic_cop.ExecuteStatementPlanGetResult(); status = traffic_cop.p_status_; traffic_cop.SetQueuing(false); } LOG_INFO("Statement executed. Result: %s", ResultTypeToString(status.m_result).c_str()); LOG_INFO("Counted Tuples!"); traffic_cop.CommitQueryHelper(); txn = txn_manager.BeginTransaction(); traffic_cop.SetTcopTxnState(txn); // Test Another delete. Should not find any tuple to be deleted LOG_INFO("Deleting a tuple..."); LOG_INFO("Query: DELETE FROM department_table WHERE dept_id < 2"); statement.reset(new Statement( "DELETE", "DELETE FROM department_table WHERE dept_id < 2")); LOG_INFO("Building parse tree..."); auto delete_stmt_2 = peloton_parser.BuildParseTree( "DELETE FROM department_table WHERE dept_id < 2"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Binding parse tree..."); parse_tree = delete_stmt_2->GetStatement(0); bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME); bind_node_visitor.BindNameToNode(parse_tree); LOG_INFO("Binding parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree(optimizer->BuildPelotonPlanTree(delete_stmt_2, txn)); LOG_INFO("Building plan tree completed!\n%s", planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str()); LOG_INFO("Executing plan..."); result_format = std::vector<int>(0, 0); TestingSQLUtil::counter_.store(1); status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result, result_format); if (traffic_cop.GetQueuing()) { TestingSQLUtil::ContinueAfterComplete(); traffic_cop.ExecuteStatementPlanGetResult(); status = traffic_cop.p_status_; traffic_cop.SetQueuing(false); } LOG_INFO("Statement executed. Result: %s", ResultTypeToString(status.m_result).c_str()); LOG_INFO("Tuple deleted!"); traffic_cop.CommitQueryHelper(); ShowTable(DEFAULT_DB_NAME, "department_table"); LOG_INFO("%s", table->GetInfo().c_str()); txn = txn_manager.BeginTransaction(); traffic_cop.SetTcopTxnState(txn); // Now deleting end-to-end LOG_INFO("Deleting a tuple..."); LOG_INFO("Query: DELETE FROM department_table"); statement.reset(new Statement("DELETE", "DELETE FROM department_table")); LOG_INFO("Building parse tree..."); auto delete_stmt = peloton_parser.BuildParseTree("DELETE FROM department_table"); LOG_INFO("Building parse tree completed!"); LOG_INFO("Binding parse tree..."); parse_tree = delete_stmt->GetStatement(0); bind_node_visitor = binder::BindNodeVisitor(txn, DEFAULT_DB_NAME); bind_node_visitor.BindNameToNode(parse_tree); LOG_INFO("Binding parse tree completed!"); LOG_INFO("Building plan tree..."); statement->SetPlanTree(optimizer->BuildPelotonPlanTree(delete_stmt, txn)); LOG_INFO("Building plan tree completed!\n%s", planner::PlanUtil::GetInfo(statement->GetPlanTree().get()).c_str()); LOG_INFO("Executing plan..."); result_format = std::vector<int>(0, 0); TestingSQLUtil::counter_.store(1); status = traffic_cop.ExecuteHelper(statement->GetPlanTree(), params, result, result_format); if (traffic_cop.GetQueuing()) { TestingSQLUtil::ContinueAfterComplete(); traffic_cop.ExecuteStatementPlanGetResult(); status = traffic_cop.p_status_; traffic_cop.SetQueuing(false); } LOG_INFO("Statement executed. Result: %s", ResultTypeToString(status.m_result).c_str()); LOG_INFO("Tuple deleted!"); traffic_cop.CommitQueryHelper(); ShowTable(DEFAULT_DB_NAME, "department_table"); LOG_INFO("%s", table->GetInfo().c_str()); // free the database just created txn = txn_manager.BeginTransaction(); catalog::Catalog::GetInstance()->DropDatabaseWithName(DEFAULT_DB_NAME, txn); txn_manager.CommitTransaction(txn); }
TEST_F(CatalogTests, CreatingTable) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); auto id_column = catalog::Column( type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "id", true); id_column.AddConstraint( catalog::Constraint(ConstraintType::PRIMARY, "primary_key")); auto name_column = catalog::Column(type::TypeId::VARCHAR, 32, "name", true); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_2( new catalog::Schema({id_column, name_column})); std::unique_ptr<catalog::Schema> table_schema_3( new catalog::Schema({id_column, name_column})); catalog::Catalog::GetInstance()->CreateTable("EMP_DB", "emp_table", std::move(table_schema), txn); catalog::Catalog::GetInstance()->CreateTable("EMP_DB", "department_table", std::move(table_schema_2), txn); catalog::Catalog::GetInstance()->CreateTable("EMP_DB", "salary_table", std::move(table_schema_3), txn); // insert random tuple into DATABASE_METRICS_CATALOG and check std::unique_ptr<type::AbstractPool> pool(new type::EphemeralPool()); catalog::DatabaseMetricsCatalog::GetInstance()->InsertDatabaseMetrics( 2, 3, 4, 5, pool.get(), txn); // oid_t time_stamp = // catalog::DatabaseMetricsCatalog::GetInstance()->GetTimeStamp(2, txn); // inset meaningless tuple into QUERY_METRICS_CATALOG and check stats::QueryMetric::QueryParamBuf param; param.len = 1; param.buf = (unsigned char *)pool->Allocate(1); *param.buf = 'a'; catalog::QueryMetricsCatalog::GetInstance()->InsertQueryMetrics( "a query", 1, 1, param, param, param, 1, 1, 1, 1, 1, 1, 1, pool.get(), txn); auto param1 = catalog::QueryMetricsCatalog::GetInstance()->GetParamTypes( "a query", 1, txn); EXPECT_EQ(1, param1.len); EXPECT_EQ('a', *param1.buf); EXPECT_EQ("name", catalog::Catalog::GetInstance() ->GetDatabaseWithName("EMP_DB", txn) ->GetTableWithName("department_table") ->GetSchema() ->GetColumn(1) .GetName()); txn_manager.CommitTransaction(txn); // EXPECT_EQ(5, time_stamp); // We remove these tests so people can add new catalogs without breaking this // test... // 3 + 4 // EXPECT_EQ(catalog::Catalog::GetInstance() // ->GetDatabaseWithName("pg_catalog") // ->GetTableWithName("pg_table") // ->GetTupleCount(), // 11); // // 6 + pg_database(2) + pg_table(3) + pg_attribute(7) + pg_index(6) // EXPECT_EQ(catalog::Catalog::GetInstance() // ->GetDatabaseWithName("pg_catalog") // ->GetTableWithName("pg_attribute") // ->GetTupleCount(), // 57); // // pg_catalog + EMP_DB // EXPECT_EQ(catalog::Catalog::GetInstance() // ->GetDatabaseWithName("pg_catalog") // ->GetTableWithName("pg_database") // ->GetTupleCount(), // 2); // // 3 + pg_index(3) + pg_attribute(3) + pg_table(3) + pg_database(2) // EXPECT_EQ(catalog::Catalog::GetInstance() // ->GetDatabaseWithName("pg_catalog") // ->GetTableWithName("pg_index") // ->GetTupleCount(), // 18); // EXPECT_EQ(catalog::Catalog::GetInstance() // ->GetDatabaseWithName("pg_catalog") // ->GetTableWithName("pg_table") // ->GetSchema() // ->GetLength(), // 72); }
TEST_F(CatalogTests, LayoutCatalogTest) { // This test creates a table, changes its layout. // Create another additional layout. // Ensure that default is not changed. // Drops layout and verifies that the default_layout is reset. // It also queries pg_layout to ensure that the entry is removed. auto db_name = "temp_db"; auto table_name = "temp_table"; auto catalog = catalog::Catalog::GetInstance(); // Create database. auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(); EXPECT_EQ(ResultType::SUCCESS, catalog->CreateDatabase(db_name, txn)); // Create table. auto val0 = catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "val0", true); auto val1 = catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "val1", true); auto val2 = catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "val2", true); auto val3 = catalog::Column(type::TypeId::INTEGER, type::Type::GetTypeSize(type::TypeId::INTEGER), "val3", true); std::unique_ptr<catalog::Schema> table_schema( new catalog::Schema({val0, val1, val2, val3})); EXPECT_EQ(ResultType::SUCCESS, catalog->CreateTable(db_name, DEFAULT_SCHEMA_NAME, table_name, std::move(table_schema), txn)); txn_manager.CommitTransaction(txn); txn = txn_manager.BeginTransaction(); auto database_oid = catalog->GetDatabaseObject(db_name, txn)->GetDatabaseOid(); auto table_object = catalog->GetTableObject(db_name, DEFAULT_SCHEMA_NAME, table_name, txn); auto table_oid = table_object->GetTableOid(); auto table = catalog->GetTableWithName(db_name, DEFAULT_SCHEMA_NAME, table_name, txn); txn_manager.CommitTransaction(txn); // Change default layout. std::map<oid_t, std::pair<oid_t, oid_t>> default_map; default_map[0] = std::make_pair(0, 0); default_map[1] = std::make_pair(0, 1); default_map[2] = std::make_pair(1, 0); default_map[3] = std::make_pair(1, 1); txn = txn_manager.BeginTransaction(); auto default_layout = catalog->CreateDefaultLayout(database_oid, table_oid, default_map, txn); txn_manager.CommitTransaction(txn); EXPECT_NE(nullptr, default_layout); // Create additional layout. std::map<oid_t, std::pair<oid_t, oid_t>> non_default_map; non_default_map[0] = std::make_pair(0, 0); non_default_map[1] = std::make_pair(0, 1); non_default_map[2] = std::make_pair(1, 0); non_default_map[3] = std::make_pair(1, 1); txn = txn_manager.BeginTransaction(); auto other_layout = catalog->CreateLayout(database_oid, table_oid, non_default_map, txn); txn_manager.CommitTransaction(txn); // Check that the default layout is still the same. EXPECT_NE(*other_layout.get(), table->GetDefaultLayout()); // Drop the default layout. auto default_layout_oid = default_layout->GetOid(); txn = txn_manager.BeginTransaction(); EXPECT_EQ(ResultType::SUCCESS, catalog->DropLayout(database_oid, table_oid, default_layout_oid, txn)); txn_manager.CommitTransaction(txn); // Check that default layout is reset and set to row_store. EXPECT_NE(*default_layout.get(), table->GetDefaultLayout()); EXPECT_TRUE(table->GetDefaultLayout().IsRowStore()); // Query pg_layout to ensure that the entry is dropped txn = txn_manager.BeginTransaction(); auto pg_layout = catalog->GetSystemCatalogs(database_oid)->GetLayoutCatalog(); EXPECT_EQ(nullptr, pg_layout->GetLayoutWithOid(table_oid, default_layout_oid, txn)); // The additional layout must be present in pg_layout auto other_layout_oid = other_layout->GetOid(); EXPECT_EQ( *(other_layout.get()), *(pg_layout->GetLayoutWithOid(table_oid, other_layout_oid, txn).get())); txn_manager.CommitTransaction(txn); // Drop database txn = txn_manager.BeginTransaction(); catalog->DropDatabaseWithName(db_name, txn); txn_manager.CommitTransaction(txn); }