bool RunMixed(ZipfDistribution &zipf, FastRandom &rng) { auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); concurrency::Transaction *txn = txn_manager.BeginTransaction(); std::unique_ptr<executor::ExecutorContext> context( new executor::ExecutorContext(txn)); // Column ids to be added to logical tile. std::vector<oid_t> 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<oid_t> key_column_ids; std::vector<ExpressionType> expr_types; key_column_ids.push_back(0); expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); std::vector<expression::AbstractExpression *> 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<type::Value > values; auto lookup_key = zipf.GetNextNumber(); values.push_back(type::ValueFactory::GetIntegerValue(lookup_key).Copy()); auto ycsb_pkey_index = user_table->GetIndexWithOid(user_table_pkey_index_oid); planner::IndexScanPlan::IndexScanDesc index_scan_desc( ycsb_pkey_index, 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(); target_list.emplace_back( col_itr, expression::ExpressionUtil::ConstantValueFactory(update_val)); } else { int update_raw_value = 1; type::Value update_val = type::ValueFactory::GetIntegerValue(update_raw_value).Copy(); target_list.emplace_back( col_itr, expression::ExpressionUtil::ConstantValueFactory(update_val)); } } else { direct_map_list.emplace_back(col_itr, std::pair<oid_t, oid_t>(0, col_itr)); } } std::unique_ptr<const planner::ProjectInfo> 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() != Result::RESULT_SUCCESS) { txn_manager.AbortTransaction(txn); return false; } } else { ///////////////////////////////////////////////////////// // PERFORM READ ///////////////////////////////////////////////////////// // set up parameter values std::vector<type::Value > values; auto lookup_key = zipf.GetNextNumber(); values.push_back(type::ValueFactory::GetIntegerValue(lookup_key).Copy()); auto ycsb_pkey_index = user_table->GetIndexWithOid(user_table_pkey_index_oid); planner::IndexScanPlan::IndexScanDesc index_scan_desc( ycsb_pkey_index, 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() != Result::RESULT_SUCCESS) { txn_manager.AbortTransaction(txn); return false; } } } // transaction passed execution. PL_ASSERT(txn->GetResult() == Result::RESULT_SUCCESS); auto result = txn_manager.CommitTransaction(txn); if (result == Result::RESULT_SUCCESS) { return true; } else { // transaction failed commitment. PL_ASSERT(result == Result::RESULT_ABORTED || result == Result::RESULT_FAILURE); return false; } }
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(); std::unique_ptr<executor::ExecutorContext> 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<oid_t> district_column_ids = {COL_IDX_D_NEXT_O_ID}; std::vector<oid_t> district_key_column_ids = {COL_IDX_D_W_ID, COL_IDX_D_ID}; std::vector<ExpressionType> district_expr_types; std::vector<common::Value *> district_key_values; std::vector<expression::AbstractExpression *> runtime_keys; district_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); district_key_values.push_back(common::ValueFactory::GetIntegerValue(w_id).Copy()); district_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); district_key_values.push_back(common::ValueFactory::GetIntegerValue(d_id).Copy()); auto district_pkey_index = district_table->GetIndexWithOid(district_table_pkey_index_oid); planner::IndexScanPlan::IndexScanDesc district_index_scan_desc( district_pkey_index, 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() != Result::RESULT_SUCCESS) { txn_manager.AbortTransaction(txn); return false; } if (districts.size() != 1) { LOG_ERROR("incorrect districts size : %lu", districts.size()); PL_ASSERT(false); } common::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 = common::ValuePeeker::PeekInteger(o_id); int min_o_id = max_o_id - 20; ////////////////////////////////////////////////////////////// std::vector<oid_t> order_line_column_ids = {COL_IDX_OL_I_ID}; std::vector<oid_t> order_line_key_column_ids = {COL_IDX_OL_W_ID, COL_IDX_OL_D_ID, COL_IDX_OL_O_ID}; std::vector<ExpressionType> order_line_expr_types; order_line_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); order_line_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); order_line_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); auto order_line_skey_index = order_line_table->GetIndexWithOid(order_line_table_skey_index_oid); ////////////////////////////////////////////////////////////// std::vector<oid_t> stock_column_ids = {COL_IDX_S_QUANTITY}; std::vector<oid_t> stock_key_column_ids = {COL_IDX_S_W_ID, COL_IDX_S_I_ID}; std::vector<ExpressionType> stock_expr_types; stock_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); stock_expr_types.push_back(ExpressionType::EXPRESSION_TYPE_COMPARE_EQUAL); auto stock_pkey_index = stock_table->GetIndexWithOid(stock_table_pkey_index_oid); ////////////////////////////////////////////////////////////// std::unordered_set<int> 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<common::Value *> order_line_key_values; order_line_key_values.push_back(common::ValueFactory::GetIntegerValue(w_id).Copy()); order_line_key_values.push_back(common::ValueFactory::GetIntegerValue(d_id).Copy()); order_line_key_values.push_back(common::ValueFactory::GetIntegerValue(curr_o_id).Copy()); planner::IndexScanPlan::IndexScanDesc order_line_index_scan_desc( order_line_skey_index, 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() != Result::RESULT_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<common::Value *> stock_key_values; stock_key_values.push_back(common::ValueFactory::GetIntegerValue(w_id).Copy()); stock_key_values.push_back(item_id); planner::IndexScanPlan::IndexScanDesc stock_index_scan_desc( stock_pkey_index, 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() != Result::RESULT_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 (common::ValuePeeker::PeekInteger(quantity) < threshold) { distinct_items.insert(common::ValuePeeker::PeekInteger(item_id)); } } LOG_TRACE("number of distinct items=%lu", distinct_items.size()); PL_ASSERT(txn->GetResult() == Result::RESULT_SUCCESS); auto result = txn_manager.CommitTransaction(txn); if (result == Result::RESULT_SUCCESS) { return true; } else { return false; } return true; }
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<expression::AbstractExpression *> runtime_keys; ///////////////////////////////////////////////////////// // BEGIN TRANSACTION ///////////////////////////////////////////////////////// auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); auto txn = txn_manager.BeginTransaction(thread_id); std::unique_ptr<executor::ExecutorContext> 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<oid_t> new_order_column_ids = {COL_IDX_NO_O_ID}; std::vector<oid_t> new_order_key_column_ids = { COL_IDX_NO_D_ID, COL_IDX_NO_W_ID, COL_IDX_NO_O_ID}; std::vector<ExpressionType> 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<type::Value> 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<oid_t> orders_column_ids = {COL_IDX_O_C_ID}; std::vector<oid_t> orders_key_column_ids = {COL_IDX_O_ID, COL_IDX_O_D_ID, COL_IDX_O_W_ID}; std::vector<ExpressionType> 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<type::Value> 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<oid_t> order_line_column_ids = {COL_IDX_OL_AMOUNT}; std::vector<oid_t> order_line_key_column_ids = { COL_IDX_OL_O_ID, COL_IDX_OL_D_ID, COL_IDX_OL_W_ID}; std::vector<ExpressionType> 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<type::Value> 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<oid_t> new_order_delete_column_ids = {0}; std::vector<ExpressionType> 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<type::Value> 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<oid_t> orders_update_column_ids = {COL_IDX_O_CARRIER_ID}; std::vector<type::Value> 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<const planner::ProjectInfo> 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<oid_t> order_line_update_column_ids = {COL_IDX_OL_DELIVERY_D}; std::vector<type::Value> 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<const planner::ProjectInfo> 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<oid_t> customer_column_ids = {COL_IDX_C_BALANCE}; std::vector<oid_t> customer_key_column_ids = {COL_IDX_C_ID, COL_IDX_C_D_ID, COL_IDX_C_W_ID}; std::vector<ExpressionType> 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<type::Value> 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<const planner::ProjectInfo> 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; } }