/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * 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_testprocs.regressionsuites.proceduredetail; import org.voltdb.ProcInfo; import org.voltdb.ProcStatsOption; import org.voltdb.SQLStmt; import org.voltdb.VoltProcedure; import org.voltdb.VoltTable; import org.voltdb.exceptions.SQLException; /* This Java stored procedure is used to test the PROCEDUREDETAIL selector in @Statistics. * It will queue batches based on the parameters you gave to test the behavior of PROCEDUREDETAIL * under different scenarios. */ @ProcInfo( partitionInfo = "ENG11890.a: 0", singlePartition = true ) @ProcStatsOption ( procSamplingInterval = 1, stmtSamplingInterval = 1 ) public class ProcedureDetailTestSP extends VoltProcedure { public final SQLStmt anInsert = new SQLStmt("INSERT INTO ENG11890 VALUES (?, ?);"); public final SQLStmt anUpdate = new SQLStmt("UPDATE ENG11890 SET b = ? WHERE a = ?;"); public final SQLStmt aDelete = new SQLStmt("DELETE FROM ENG11890 WHERE a = ?;"); public final SQLStmt aSelect = new SQLStmt("SELECT * FROM ENG11890 WHERE a = ? ORDER BY a;"); public VoltTable[] run(int id, String arg) throws VoltAbortException { /* Parse the options in a simple way: * * rw: option to queue a batch that has both read and write operations. * This is particularly useful to test multi-partition stored procedure details. * For multi-partition stored procedures, there are different code paths for * homogeneous batches (pure read or pure write) and * heterogeneous batches (has both read and write). */ boolean hasReadWrite = arg.contains("readwrite"); // failure: throw an exception to cause the procedure to fail. boolean hasFailure = arg.contains("failure"); // abort: option to queue a batch with a query which can cause the procedure to abort. boolean hasAbort = arg.contains("abort"); /* 2batch: option to issue two batches in the stored procedure. * if the "err" option is enabled, the failing statement will be queued in the * first batch and the exception will be caught and extinguished. * So you will see in the procedure detail statistics that the procedure * succeeded but one of the statements has the failure count = 1 :) */ boolean twoBatches = arg.contains("twobatch"); // Start to queue the first batch: voltQueueSQL(anInsert, id, String.valueOf(id)); voltQueueSQL(anUpdate, String.valueOf(id + 1), id); if (hasReadWrite) { voltQueueSQL(aSelect, id); } if (hasAbort) { voltQueueSQL(anInsert, id, "012345678910"); // overflow } voltQueueSQL(aDelete, id); try { voltExecuteSQL(! twoBatches); } catch (SQLException ex) { if (twoBatches || hasFailure) { System.out.println("\nCaught exception as expected:\n" + ex.getMessage()); System.out.print("This procedure is configured to execute another batch or needs to fail later, "); System.out.println("so this exception is extinguished."); } else { throw ex; } } if (hasFailure) { throw new RuntimeException("Procedure failed as requested in the parameter."); } if (! twoBatches) { return null; } // Start to queue the second batch, if asked: voltQueueSQL(anInsert, id, String.valueOf(id)); voltQueueSQL(anUpdate, String.valueOf(id + 1), id); if (hasReadWrite) { voltQueueSQL(aSelect, id); } voltQueueSQL(aDelete, id); voltExecuteSQL(true); return null; } }