public void testAggregatesOnEmptyTable() throws IOException, ProcCallException { String[] aggs = {"count", "sum", "min", "max"}; String[] tables = {"P1", "R1"}; for (String table : tables) { Client client = getClient(); for (int i = 0; i < aggs.length; ++i) { String query = String.format("select %s(%s.NUM) from %s", aggs[i], table, table); VoltTable[] results = client.callProcedure("@AdHoc", query).getResults(); if (aggs[i].equals("count")) { assertEquals(0, results[0].asScalarLong()); } else { final VoltTableRow row = results[0].fetchRow(0); row.get(0, results[0].getColumnType(0)); if (!isHSQL()) { assertTrue(row.wasNull()); } } } // Do avg separately since the column is a float and makes // asScalarLong() unhappy String query = String.format("select avg(%s.NUM) from %s", table, table); VoltTable[] results = client.callProcedure("@AdHoc", query).getResults(); results[0].advanceRow(); @SuppressWarnings("unused") final double value = ((Number) results[0].get(0, results[0].getColumnType(0))).doubleValue(); if (!isHSQL()) { assertTrue(results[0].wasNull()); } } }
public VoltTable run(short w_id, int o_carrier_id, TimestampType timestamp) throws VoltAbortException { for (long d_id = 1; d_id <= Constants.DISTRICTS_PER_WAREHOUSE; ++d_id) { voltQueueSQL(getNewOrder, d_id, w_id); } final VoltTable[] neworderresults = voltExecuteSQL(); assert neworderresults.length == Constants.DISTRICTS_PER_WAREHOUSE; final Long[] no_o_ids = new Long[Constants.DISTRICTS_PER_WAREHOUSE]; int valid_neworders = 0; int[] result_offsets = new int[Constants.DISTRICTS_PER_WAREHOUSE]; for (long d_id = 1; d_id <= Constants.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 <= Constants.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 <= Constants.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. 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(); return result; }