@Test public void testFinishedSPAdHocPlanning() throws Exception { // Need a batch and a statement AdHocPlannedStmtBatch plannedStmtBatch = new AdHocPlannedStmtBatch( "select * from a where i = 3", 3, 0, 0, "localhost", false, ProcedureInvocationType.ORIGINAL, 0, 0, null); AdHocPlannedStatement s = new AdHocPlannedStatement( "select * from a where i = 3".getBytes(Constants.UTF8ENCODING), new CorePlan( new byte[0], null, new byte[20], null, false, false, true, new VoltType[0], 0), ParameterSet.fromArrayNoCopy(new Object[0]), null, null, 3); plannedStmtBatch.addStatement(s); m_ci.processFinishedCompilerWork(plannedStmtBatch).run(); ArgumentCaptor<Long> destinationCaptor = ArgumentCaptor.forClass(Long.class); ArgumentCaptor<Iv2InitiateTaskMessage> messageCaptor = ArgumentCaptor.forClass(Iv2InitiateTaskMessage.class); verify(m_messenger).send(destinationCaptor.capture(), messageCaptor.capture()); Iv2InitiateTaskMessage message = messageCaptor.getValue(); assertTrue(message.isReadOnly()); // readonly assertTrue(message.isSinglePartition()); // single-part assertEquals("@AdHoc_RO_SP", message.getStoredProcedureName()); // SP AdHoc should have partitioning parameter serialized in the parameter set Object partitionParam = message.getStoredProcedureInvocation().getParameterAtIndex(0); assertTrue(partitionParam instanceof byte[]); VoltType type = VoltType.get((Byte) message.getStoredProcedureInvocation().getParameterAtIndex(1)); assertTrue(type.isInteger()); byte[] serializedData = (byte[]) message.getStoredProcedureInvocation().getParameterAtIndex(2); AdHocPlannedStatement[] statements = AdHocPlannedStmtBatch.planArrayFromBuffer(ByteBuffer.wrap(serializedData)); assertTrue(Arrays.equals(TheHashinator.valueToBytes(3), (byte[]) partitionParam)); assertEquals(1, statements.length); String sql = new String(statements[0].sql, Constants.UTF8ENCODING); assertEquals("select * from a where i = 3", sql); }
@Override public void run() { // ratio of upsert for @Load*Table final float upsertratio = 0.50F; // ratio of upsert to an existing table for @Load*Table final float upserthitratio = 0.20F; CopyAndDeleteDataTask cdtask = new CopyAndDeleteDataTask(); cdtask.start(); try { while (m_shouldContinue.get()) { // 1 in 3 gets copied and then deleted after leaving some data byte shouldCopy = (byte) (m_random.nextInt(3) == 0 ? 1 : 0); byte upsertMode = (byte) (m_random.nextFloat() < upsertratio ? 1 : 0); byte upsertHitMode = (byte) ((upsertMode != 0) && (m_random.nextFloat() < upserthitratio) ? 1 : 0); CountDownLatch latch = new CountDownLatch(batchSize); final ArrayList<Long> lcpDelQueue = new ArrayList<Long>(); // try to insert batchSize random rows for (int i = 0; i < batchSize; i++) { m_table.clearRowData(); m_permits.acquire(); long p = Math.abs(r.nextLong()); m_table.addRow(p, p, Calendar.getInstance().getTimeInMillis()); boolean success = false; if (!m_isMP) { Object rpartitionParam = TheHashinator.valueToBytes( m_table.fetchRow(0).get(m_partitionedColumnIndex, VoltType.BIGINT)); if (upsertHitMode != 0) { // for test upsert an existing row, insert it and then upsert same row // again. success = client.callProcedure( new InsertCallback(latch, p, shouldCopy), m_procName, rpartitionParam, m_tableName, (byte) 1, m_table); } success = client.callProcedure( new InsertCallback(latch, p, shouldCopy), m_procName, rpartitionParam, m_tableName, (byte) 1, m_table); } else { if (upsertHitMode != 0) { success = client.callProcedure( new InsertCallback(latch, p, shouldCopy), m_procName, m_tableName, (byte) 1, m_table); } success = client.callProcedure( new InsertCallback(latch, p, shouldCopy), m_procName, m_tableName, (byte) 1, m_table); } // Ad if successfully queued but remove if proc fails. if (success) { if (shouldCopy != 0) { lcpDelQueue.add(p); } else { onlyDelQueue.add(p); } } } // Wait for all @Load{SP|MP}Done latch.await(); cpDelQueue.addAll(lcpDelQueue); long nextRowCount = 0; try { nextRowCount = TxnId2Utils.getRowCount(client, m_tableName); } catch (Exception e) { hardStop("getrowcount exception", e); } // if no progress, throttle a bit if (nextRowCount == currentRowCount.get()) { Thread.sleep(1000); } if (onlyDelQueue.size() > 0 && m_shouldContinue.get()) { List<Long> workList = new ArrayList<Long>(); onlyDelQueue.drainTo(workList); CountDownLatch odlatch = new CountDownLatch(workList.size()); for (Long lcid : workList) { client.callProcedure(new DeleteCallback(odlatch, 1), m_onlydelprocName, lcid); } odlatch.await(); } } // Any accumulated in p/mp tables are left behind. } catch (Exception e) { // on exception, log and end the thread, but don't kill the process log.error( "LoadTableLoader failed a procedure call for table " + m_tableName + " and the thread will now stop.", e); } finally { cdtask.shutdown(); try { cdtask.join(); } catch (InterruptedException ex) { log.error("CopyDelete Task was stopped.", ex); } } }