private void checkNotNull(ElementSymbol param, Object value) throws TeiidComponentException, QueryMetadataException, QueryValidatorException { if (metadata.elementSupports(param.getMetadataID(), SupportConstants.Element.NULL)) { return; } if (metadata.isVariadic(param.getMetadataID())) { if (value instanceof ArrayImpl) { ArrayImpl av = (ArrayImpl) value; for (Object o : av.getValues()) { if (o == null) { throw new QueryValidatorException( QueryPlugin.Event.TEIID30164, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30164, param)); } } } } else if (value == null) { throw new QueryValidatorException( QueryPlugin.Event.TEIID30164, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30164, param)); } }
/** * @param command * @param rsName * @param procAssignments * @param mode * @param usesLocalTemp - only matters in HOLD mode * @throws TeiidComponentException * @throws TeiidProcessingException */ public void executePlan( ProcessorPlan command, String rsName, Map<ElementSymbol, ElementSymbol> procAssignments, CreateCursorResultSetInstruction.Mode mode, boolean usesLocalTemp) throws TeiidComponentException, TeiidProcessingException { CursorState state = (CursorState) this.cursorStates.getValue(rsName); if (state == null || rsName == null) { if (this.currentState != null && this.currentState.processor.getProcessorPlan() != command) { // sanity check for non-deterministic paths removeState(this.currentState); this.currentState = null; } if (this.currentState == null) { // this may not be the first time the plan is being run command.reset(); CommandContext subContext = getContext().clone(); subContext.setVariableContext(this.currentVarContext); state = new CursorState(); state.usesLocalTemp = usesLocalTemp; state.processor = new QueryProcessor(command, subContext, this.bufferMgr, this); state.ts = new BatchIterator(state.processor); if (mode == Mode.HOLD && procAssignments != null && state.processor.getOutputElements().size() - procAssignments.size() > 0) { state.resultsBuffer = bufferMgr.createTupleBuffer( state .processor .getOutputElements() .subList( 0, state.processor.getOutputElements().size() - procAssignments.size()), getContext().getConnectionId(), TupleSourceType.PROCESSOR); } else if ((this.blockContext != null || this.programs.peek().isTrappingExceptions()) && (mode == Mode.HOLD || rsName != null)) { state.resultsBuffer = bufferMgr.createTupleBuffer( state.processor.getOutputElements(), getContext().getConnectionId(), TupleSourceType.PROCESSOR); } this.currentState = state; } // force execution to the first batch to ensure that the plan is executed in the context of // the procedure this.currentState.ts.hasNext(); if (procAssignments != null) { // proc assignments force us to scroll through the entire results and save as we go while (this.currentState.ts.hasNext()) { if (this.currentState.currentRow != null && this.currentState.resultsBuffer != null) { this.currentState.resultsBuffer.addTuple( this.currentState.currentRow.subList( 0, this.currentState.resultsBuffer.getSchema().size())); this.currentState.currentRow = null; } this.currentState.currentRow = this.currentState.ts.nextTuple(); } // process assignments Assertion.assertTrue(this.currentState.currentRow != null); for (Map.Entry<ElementSymbol, ElementSymbol> entry : procAssignments.entrySet()) { if (entry.getValue() == null || !metadata.elementSupports( entry.getValue().getMetadataID(), SupportConstants.Element.UPDATE)) { continue; } int index = this.currentState.processor.getOutputElements().indexOf(entry.getKey()); getCurrentVariableContext() .setValue( entry.getValue(), DataTypeManager.transformValue( this.currentState.currentRow.get(index), entry.getValue().getType())); } } else if (this.currentState.resultsBuffer != null) { // result should be saved, typically to respect txn semantics while (this.currentState.ts.hasNext()) { List<?> tuple = this.currentState.ts.nextTuple(); this.currentState.resultsBuffer.addTuple(tuple); } getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, 0); } else if (mode == Mode.UPDATE) { List<?> t = this.currentState.ts.nextTuple(); if (this.currentState.ts.hasNext()) { throw new AssertionError( "Invalid update count result - more than 1 row returned"); //$NON-NLS-1$ } removeState(this.currentState); this.currentState = null; int rowCount = 0; if (t != null) { rowCount = (Integer) t.get(0); } getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, rowCount); return; } if (rsName == null && mode == Mode.NOHOLD) { // unnamed without hold // process fully, but don't save // TODO: could set the rowcount in this case while (this.currentState.ts.hasNext()) { this.currentState.ts.nextTuple(); } this.currentState = null; getCurrentVariableContext().setValue(ProcedurePlan.ROWCOUNT, 0); return; } if (this.currentState.resultsBuffer != null) { // close the results buffer and use a buffer backed tuplesource this.currentState.resultsBuffer.close(); this.currentState.ts = this.currentState.resultsBuffer.createIndexedTupleSource(true); } CursorState old = (CursorState) this.cursorStates.setValue(rsName, this.currentState); if (old != null) { removeState(old); } this.currentState = null; } }