public void helpTestProcessor(FakeProcessorPlan plan, List[] expectedResults) throws TeiidException { BufferManager bufferMgr = BufferManagerFactory.getStandaloneBufferManager(); FakeDataManager dataManager = new FakeDataManager(); CommandContext context = new CommandContext("pid", "group", null, null, 1); // $NON-NLS-1$ //$NON-NLS-2$ QueryProcessor processor = new QueryProcessor(plan, context, bufferMgr, dataManager); BatchCollector collector = processor.createBatchCollector(); TupleBuffer tsID = null; while (true) { try { tsID = collector.collectTuples(); break; } catch (BlockedException e) { } } // Compare # of rows in actual and expected assertEquals( "Did not get expected # of rows", expectedResults.length, tsID.getRowCount()); // $NON-NLS-1$ // Compare actual with expected results TupleSource actual = tsID.createIndexedTupleSource(); if (expectedResults.length > 0) { for (int i = 0; i < expectedResults.length; i++) { List actRecord = actual.nextTuple(); List expRecord = expectedResults[i]; assertEquals("Did not match row at row index " + i, expRecord, actRecord); // $NON-NLS-1$ } } tsID.remove(); }
@Test public void testLobHandling() throws Exception { ElementSymbol x = new ElementSymbol("x"); // $NON-NLS-1$ x.setType(DataTypeManager.DefaultDataClasses.CLOB); List<ElementSymbol> schema = Arrays.asList(x); TupleBuffer tb = BufferManagerFactory.getStandaloneBufferManager() .createTupleBuffer(schema, "x", TupleSourceType.PROCESSOR); // $NON-NLS-1$ tb.setInlineLobs(false); ClobType c = new ClobType(new SerialClob(new char[0])); TupleBatch batch = new TupleBatch(1, new List[] {Arrays.asList(c)}); tb.addTupleBatch(batch, false); assertNotNull(tb.getLobReference(c.getReferenceStreamId())); }
@Test public void testForwardOnly() throws Exception { ElementSymbol x = new ElementSymbol("x"); // $NON-NLS-1$ x.setType(DataTypeManager.DefaultDataClasses.INTEGER); List<ElementSymbol> schema = Arrays.asList(x); TupleBuffer tb = BufferManagerFactory.getStandaloneBufferManager() .createTupleBuffer(schema, "x", TupleSourceType.PROCESSOR); // $NON-NLS-1$ tb.setForwardOnly(true); tb.addTuple(Arrays.asList(1)); TupleBatch batch = tb.getBatch(1); assertTrue(!batch.getTerminationFlag()); assertEquals(1, batch.getBeginRow()); try { tb.getBatch(1); fail("expected exception"); // $NON-NLS-1$ } catch (AssertionError e) { } tb.addTuple(Arrays.asList(1)); tb.close(); batch = tb.getBatch(2); assertTrue(batch.getTerminationFlag()); assertEquals(2, batch.getBeginRow()); }
/** * @throws TeiidComponentException * @see * org.teiid.query.sql.util.ValueIteratorSource#getValueIterator(org.teiid.query.sql.symbol.Expression) */ public TupleSourceValueIterator getValueIterator(Expression valueExpression) throws TeiidComponentException { IndexedTupleSource its = buffer.createIndexedTupleSource(); int index = 0; if (valueExpression != null) { if (valueExpression instanceof Array) { final Array array = (Array) valueExpression; List<Expression> exprs = array.getExpressions(); final int[] indexes = new int[exprs.size()]; for (int i = 0; i < exprs.size(); i++) { indexes[i] = getIndex(exprs.get(i)); } return new TupleSourceValueIterator(its, index) { @Override public Object next() throws TeiidComponentException { List<?> tuple = super.nextTuple(); Object[] a = (Object[]) java.lang.reflect.Array.newInstance(array.getComponentType(), indexes.length); for (int i = 0; i < indexes.length; i++) { a[i] = tuple.get(indexes[i]); if (a[i] == null) { return null; // TODO: this is a hack } } return new ArrayImpl(a); } }; } index = getIndex(valueExpression); } return new TupleSourceValueIterator(its, index); }
public Set<Object> getCachedSet(Expression valueExpression) throws TeiidComponentException, TeiidProcessingException { Set<Object> result = null; if (cachedSets != null) { result = cachedSets.get(valueExpression); } if (result == null) { if (buffer.getRowCount() > buffer.getBatchSize()) { return null; } TupleSourceValueIterator ve = getValueIterator(valueExpression); int index = 0; Class<?> type = null; if (valueExpression instanceof Array) { type = ((Array) valueExpression).getComponentType(); } else { if (valueExpression != null) { index = schema.indexOf(valueExpression); Assertion.assertTrue(index != -1); } type = ((Expression) schema.get(index)).getType(); } if (!DataTypeManager.isHashable(type)) { result = new TreeSet<Object>(Constant.COMPARATOR); } else { result = new HashSet<Object>(); } while (ve.hasNext()) { Object value = ve.next(); if (value != null) { result.add(value); } } ve.close(); if (cachedSets == null) { cachedSets = new HashMap<Expression, Set<Object>>(); } cachedSets.put(valueExpression, result); } return result; }
public DependentValueSource(TupleBuffer tb) { this(tb, tb.getSchema()); }
/** * Get batch from child node Walk through each row of child batch Bind values to insertCommand * Execute insertCommand Update insertCount When no more data is available, output batch with * single row containing insertCount */ public TupleBatch nextBatchDirect() throws BlockedException, TeiidComponentException, TeiidProcessingException { while (phase == REQUEST_CREATION) { checkExitConditions(); /* If we don't have a batch to work, get the next */ if (currentBatch == null) { if (sourceDone) { phase = RESPONSE_PROCESSING; break; } currentBatch = getChildren()[0].nextBatch(); // can throw BlockedException sourceDone = currentBatch.getTerminationFlag(); this.batchRow = currentBatch.getBeginRow(); // normally we would want to skip a 0 sized batch, but it typically represents the terminal // batch // and for implicit temp tables we need to issue an empty insert if (currentBatch.getRowCount() == 0 && (!currentBatch.getTerminationFlag() || mode != Mode.ITERATOR)) { currentBatch = null; continue; } } int batchSize = currentBatch.getRowCount(); int requests = 1; switch (mode) { case ITERATOR: if (buffer == null) { buffer = getBufferManager() .createTupleBuffer(intoElements, getConnectionID(), TupleSourceType.PROCESSOR); } buffer.addTupleBatch(currentBatch, true); if (currentBatch.getTerminationFlag() && (buffer.getRowCount() != 0 || intoGroup.isImplicitTempGroupSymbol())) { Insert insert = new Insert(intoGroup, intoElements, null); buffer.close(); insert.setTupleSource(buffer.createIndexedTupleSource(true)); // Register insert command against source registerRequest(insert); } else { requests = 0; } break; case BATCH: // Register batched update command against source int endRow = currentBatch.getEndRow(); List<Command> rows = new ArrayList<Command>(endRow - batchRow); for (int rowNum = batchRow; rowNum <= endRow; rowNum++) { Insert insert = new Insert( intoGroup, intoElements, convertValuesToConstants(currentBatch.getTuple(rowNum), intoElements)); rows.add(insert); } registerRequest(new BatchedUpdateCommand(rows)); break; case SINGLE: batchSize = 1; // Register insert command against source // Defect 16036 - submit a new INSERT command to the DataManager. registerRequest( new Insert( intoGroup, intoElements, convertValuesToConstants(currentBatch.getTuple(batchRow), intoElements))); } this.batchRow += batchSize; if (batchRow > currentBatch.getEndRow()) { currentBatch = null; } this.requestsRegistered += requests; } checkExitConditions(); // End this node's work addBatchRow(Arrays.asList(insertCount)); terminateBatches(); return pullBatch(); }
@Test public void testTruncate() throws Exception { ElementSymbol x = new ElementSymbol("x"); // $NON-NLS-1$ x.setType(DataTypeManager.DefaultDataClasses.INTEGER); List<ElementSymbol> schema = Arrays.asList(x); TupleBuffer tb = BufferManagerFactory.getStandaloneBufferManager() .createTupleBuffer(schema, "x", TupleSourceType.PROCESSOR); // $NON-NLS-1$ tb.setBatchSize(2); for (int i = 0; i < 5; i++) { tb.addTuple(Arrays.asList(1)); } TupleBatch batch = tb.getBatch(1); assertTrue(!batch.getTerminationFlag()); assertEquals(2, batch.getEndRow()); tb.close(); assertEquals(5, tb.getManagedRowCount()); tb.truncateTo(3); assertEquals(3, tb.getManagedRowCount()); assertEquals(3, tb.getRowCount()); batch = tb.getBatch(3); assertTrue(batch.getTerminationFlag()); tb.truncateTo(2); assertEquals(2, tb.getManagedRowCount()); assertEquals(2, tb.getRowCount()); batch = tb.getBatch(2); assertTrue(batch.getTerminationFlag()); }
private TupleSource handleCachedProcedure(final CommandContext context, StoredProcedure proc) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException { String fullName = context.getMetadata().getFullName(proc.getProcedureID()); LogManager.logDetail( LogConstants.CTX_DQP, "processing cached procedure request for", fullName); // $NON-NLS-1$ LinkedList<Object> vals = new LinkedList<Object>(); for (SPParameter param : proc.getInputParameters()) { vals.add(((Constant) param.getExpression()).getValue()); } // collapse the hash to single byte for the key to restrict the possible results to 256 int hash = vals.hashCode(); hash |= (hash >>> 16); hash |= (hash >>> 8); hash &= 0x000000ff; final CacheID cid = new CacheID( new ParseInfo(), fullName + hash, context.getVdbName(), context.getVdbVersion(), context.getConnectionId(), context.getUserName()); cid.setParameters(vals); CachedResults results = cache.get(cid); if (results != null) { TupleBuffer buffer = results.getResults(); return buffer.createIndexedTupleSource(); } // construct a query with a no cache hint final CacheHint hint = proc.getCacheHint(); proc.setCacheHint(null); Option option = new Option(); option.setNoCache(true); option.addNoCacheGroup(fullName); proc.setOption(option); StoredProcedure cloneProc = (StoredProcedure) proc.clone(); int i = 0; for (SPParameter param : cloneProc.getInputParameters()) { param.setExpression(new Reference(i++)); } final QueryProcessor qp = context .getQueryProcessorFactory() .createQueryProcessor( cloneProc.toString(), fullName.toUpperCase(), context, vals.toArray()); final BatchCollector bc = qp.createBatchCollector(); return new ProxyTupleSource() { boolean success = false; @Override protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException { TupleBuffer tb = bc.collectTuples(); CachedResults cr = new CachedResults(); cr.setResults(tb, qp.getProcessorPlan()); Determinism determinismLevel = qp.getContext().getDeterminismLevel(); if (hint != null && hint.getDeterminism() != null) { LogManager.logTrace( LogConstants.CTX_DQP, new Object[] { "Cache hint modified the query determinism from ", determinismLevel, " to ", hint.getDeterminism() }); //$NON-NLS-1$ //$NON-NLS-2$ determinismLevel = hint.getDeterminism(); } cache.put(cid, determinismLevel, cr, hint != null ? hint.getTtl() : null); context.setDeterminismLevel(determinismLevel); success = true; return tb.createIndexedTupleSource(); } @Override public void closeSource() { super.closeSource(); qp.closeProcessing(); if (!success && bc.getTupleBuffer() != null) { bc.getTupleBuffer().remove(); } } }; }