/* This file is part of VoltDB. * Copyright (C) 2008-2010 VoltDB L.L.C. * * This file contains original code and/or modifications of original code. * Any modifications made by VoltDB L.L.C. are licensed under the following * terms and conditions: * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* Copyright (C) 2008 * Michael McCanna * Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ package org.voltdb.benchmark.tpcc.procedures; import org.voltdb.ProcInfo; import org.voltdb.SQLStmt; import org.voltdb.VoltProcedure; import org.voltdb.VoltTable; import org.voltdb.VoltTableRow; import org.voltdb.VoltType; import org.voltdb.benchmark.tpcc.TPCCConstants; import org.voltdb.types.TimestampType; @ProcInfo ( partitionInfo = "WAREHOUSE.W_ID: 0", singlePartition = true ) public class delivery extends VoltProcedure { private final VoltTable result_template = new VoltTable( new VoltTable.ColumnInfo("d_id", VoltType.TINYINT), new VoltTable.ColumnInfo("o_id", VoltType.INTEGER) ); //BLOCK: Replaces use of cursor with a limited select. public final SQLStmt getNewOrder = new SQLStmt("SELECT NO_O_ID FROM NEW_ORDER WHERE NO_D_ID = ? AND NO_W_ID = ? AND NO_O_ID > -1 LIMIT 1;"); public final SQLStmt deleteNewOrder = new SQLStmt("DELETE FROM NEW_ORDER WHERE NO_D_ID = ? AND NO_W_ID = ? AND NO_O_ID = ?;"); // d_id, w_id, no_o_id //END OF BLOCK public final SQLStmt getCId = new SQLStmt("SELECT O_C_ID FROM ORDERS WHERE O_ID = ? AND O_D_ID = ? AND O_W_ID = ?;"); //no_o_id, d_id, w_id //into c_id public final SQLStmt updateOrders = new SQLStmt("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 public final SQLStmt updateOrderLine = new SQLStmt("UPDATE ORDER_LINE SET OL_DELIVERY_D = ? WHERE OL_O_ID = ? AND OL_D_ID = ? AND OL_W_ID = ?;"); //timestamp, no_o_id, d_id, w_id //is ol_amount a column? assuming so (and that this sum() is being supported) public final SQLStmt sumOLAmount = new SQLStmt("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 //into ol_total public final SQLStmt updateCustomer = new SQLStmt("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 public VoltTable run(short w_id, int o_carrier_id, TimestampType timestamp) throws VoltAbortException { for (long d_id = 1; d_id <= TPCCConstants.DISTRICTS_PER_WAREHOUSE; ++d_id) { voltQueueSQL(getNewOrder, d_id, w_id); } final VoltTable[] neworderresults = voltExecuteSQL(); assert neworderresults.length == TPCCConstants.DISTRICTS_PER_WAREHOUSE; final Long[] no_o_ids = new Long[TPCCConstants.DISTRICTS_PER_WAREHOUSE]; int valid_neworders = 0; int[] result_offsets = new int[TPCCConstants.DISTRICTS_PER_WAREHOUSE]; for (long d_id = 1; d_id <= TPCCConstants.DISTRICTS_PER_WAREHOUSE; ++d_id) { final VoltTable newOrder = neworderresults[(int) d_id - 1]; if (newOrder.getRowCount() == 0) { // No orders for this district: skip it. Note: This must be reported if > 1% result_offsets[(int) d_id - 1] = -1; continue; } assert newOrder.getRowCount() == 1; result_offsets[(int) d_id - 1] = valid_neworders * 2; ++valid_neworders; final Long no_o_id = newOrder.asScalarLong(); no_o_ids[(int) d_id - 1] = no_o_id; voltQueueSQL(getCId, no_o_id, d_id, w_id); voltQueueSQL(sumOLAmount, no_o_id, d_id, w_id); } final VoltTable[] otherresults = voltExecuteSQL(); assert otherresults.length == valid_neworders * 2; for (long d_id = 1; d_id <= TPCCConstants.DISTRICTS_PER_WAREHOUSE; ++d_id) { final VoltTable newOrder = neworderresults[(int) d_id - 1]; if (newOrder.getRowCount() == 0) { // No orders for this district: skip it. Note: This must be reported if > 1% continue; } assert newOrder.getRowCount() == 1; final Long no_o_id = newOrder.asScalarLong(); no_o_ids[(int) d_id - 1] = no_o_id; voltQueueSQL(deleteNewOrder, d_id, w_id, no_o_id); voltQueueSQL(updateOrders, o_carrier_id, no_o_id, d_id, w_id); voltQueueSQL(updateOrderLine, timestamp, no_o_id, d_id, w_id); } voltExecuteSQL(); // these must be logged in the "result file" according to TPC-C 2.7.2.2 (page 39) // We remove the queued time, completed time, w_id, and o_carrier_id: the client can figure // them out final VoltTable result = result_template.clone(1024); for (long d_id = 1; d_id <= TPCCConstants.DISTRICTS_PER_WAREHOUSE; ++d_id) { int resultoffset = result_offsets[(int) d_id - 1]; if (resultoffset < 0) { continue; } assert otherresults[resultoffset + 0].getRowCount() == 1; assert otherresults[resultoffset + 1].getRowCount() == 1; final long c_id = (otherresults[resultoffset + 0].asScalarLong()); final VoltTableRow row = otherresults[resultoffset + 1].fetchRow(0); final double ol_total = row.getDouble(0); final boolean ol_total_wasnull = row.wasNull(); // If there are no order lines, SUM returns null. There should always be order lines. /* FIXME if (ol_total_wasnull) { throw new VoltAbortException( "ol_total is NULL: there are no order lines. This should not happen"); } assert ol_total > 0.0; */ voltQueueSQL(updateCustomer, ol_total, c_id, d_id, w_id); final Long no_o_id = no_o_ids[(int) d_id - 1]; result.addRow(d_id, no_o_id); } voltExecuteSQL(true); return result; } }