BOOL CCLITerminal::InputStream(CLISESSION *pSession, const unsigned char *pszBuffer, int nLength) { unsigned char cc; int i, nVKey; if (pSession->pWorker != NULL) { // 이미 수행중인 작업이 있는 경우 return TRUE; } for(i=0; i<nLength; i++) { cc = pszBuffer[i]; retry_loop: switch(pSession->nState) { case TS_CR : if (cc == '\n') break; // Do not break pSession->nState = TS_DATA; case TS_DATA : switch(cc) { case 0x00 : break; case IAC : pSession->nState = TS_IAC; break; case KEY_BS : ExecuteBackspace(pSession); break; case KEY_DEL : ExecuteDelete(pSession); break; case KEY_TAB : if (!pSession->bLogined) break; ExecuteTab(pSession); break; case '?' : if (!pSession->bLogined) break; ExecuteInlineHelp(pSession); break; case KEY_ESC : pSession->nState = TS_ESC; break; case KEY_CTRL_D : // exit(0); return FALSE; default : // if (!pSession->nLocalOptions[TELOPT_BINARY] && (cc == '\r')) if (cc == '\r') { if (!ExecuteCommand(pSession)) return FALSE; pSession->nState = TS_CR; break; } if (IsPrintable(cc) && ((pSession->nCmdLength+1)<=CLIMAX_COMMAND_SIZE)) { pSession->szCommand[pSession->nCmdLength] = cc; pSession->nCmdLength++; if (pSession->bNeedUser) WriteChar(pSession, cc); else WriteChar(pSession, pSession->bLogined ? cc : '*'); } break; } break; case TS_ESC : if ((cc != '[') && (cc != 'O')) { pSession->nState = TS_DATA; goto retry_loop; } pSession->nVKeyCount = 0; pSession->nState = TS_ESCSEQ; case TS_ESCSEQ : if (pSession->nVKeyCount >= MAX_VIRTUAL_KEY_SIZE) { pSession->nState = TS_DATA; goto retry_loop; } pSession->szVKeyBuffer[pSession->nVKeyCount] = cc; pSession->nVKeyCount++; pSession->szVKeyBuffer[pSession->nVKeyCount] = '\0'; nVKey = FindVirtualKey(pSession); if (nVKey >= 0) { ExecuteVirtualKey(pSession, nVKey); pSession->nState = TS_DATA; } else if (nVKey == -1) { pSession->nState = TS_DATA; goto retry_loop; } break; case TS_IAC : switch(cc) { case BREAK : case IP : pSession->nState = TS_DATA; break; case AYT : WriteStream(pSession, (char *)aytreply, strlen((char *)aytreply)); pSession->nState = TS_DATA; break; case AO : WriteStream(pSession, (char *)aoreply, 2); pSession->nState = TS_DATA; break; case EC : WriteStream(pSession, "\b", 1); pSession->nState = TS_DATA; break; case EL : WriteStream(pSession, "\025", 1); pSession->nState = TS_DATA; break; case DM : pSession->nState = TS_DATA; break; case SB : pSession->nState = TS_SB; break; case WILL : pSession->nState = TS_WILL; break; case WONT : pSession->nState = TS_WONT; break; case DO : pSession->nState = TS_DO; break; case DONT : pSession->nState = TS_DONT; break; case IAC : WriteChar(pSession, cc); pSession->nState = TS_DATA; break; default : pSession->nState = TS_DATA; break; } break; case TS_SB : if (cc == IAC) pSession->nState = TS_SE; break; case TS_SE : pSession->nState = (cc == SE) ? TS_DATA : TS_SB; break; case TS_WILL : //printf("IAC WILL %0d\n", cc); RemoteDoOption(pSession, (int)cc, TRUE, TRUE); pSession->nState = TS_DATA; break; case TS_WONT : //printf("IAC WONT %0d\n", cc); RemoteDoOption(pSession, (int)cc, FALSE, TRUE); pSession->nState = TS_DATA; break; case TS_DO : //printf("IAC DO %0d\n", cc); LocalDoOption(pSession, (int)cc, TRUE, TRUE); pSession->nState = TS_DATA; break; case TS_DONT : //printf("IAC DONT %0d\n", cc); LocalDoOption(pSession, (int)cc, FALSE, TRUE); pSession->nState = TS_DATA; break; } } 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; } }