@Override
protected ValueIterator evaluateSubquery(SubqueryContainer container,
List tuple) throws TeiidProcessingException, BlockedException,
TeiidComponentException {
ContextReference ref = (ContextReference)container;
String key = (ref).getContextSymbol();
SubqueryState state = this.subqueries.get(key);
if (state == null) {
state = new SubqueryState();
state.plan = container.getCommand().getProcessorPlan().clone();
if (container instanceof ScalarSubquery) {
state.nonDeterministic = FunctionCollectorVisitor.isNonDeterministic(container.getCommand());
}
if (container.getCommand().getCorrelatedReferences() != null) {
for (ElementSymbol es : container.getCommand().getCorrelatedReferences().getKeys()) {
if (DataTypeManager.isNonComparable(DataTypeManager.getDataTypeName(es.getType()))) {
state.comparable = false;
break;
}
}
}
this.subqueries.put(key, state);
}
SymbolMap correlatedRefs = container.getCommand().getCorrelatedReferences();
VariableContext currentContext = null;
boolean shouldClose = state.done && state.nonDeterministic;
if (correlatedRefs != null) {
currentContext = new VariableContext();
for (Map.Entry<ElementSymbol, Expression> entry : container.getCommand().getCorrelatedReferences().asMap().entrySet()) {
currentContext.setValue(entry.getKey(), evaluate(entry.getValue(), tuple));
}
List<Object> refValues = currentContext.getLocalValues();
if (!refValues.equals(state.refValues)) {
state.refValues = refValues;
shouldClose = true;
}
}
if (shouldClose) {
//if (state.done && state.comparable) {
//cache
//} else {
state.close();
//}
}
if (!state.done) {
if (state.processor == null) {
CommandContext subContext = context.clone();
state.plan.reset();
state.processor = new QueryProcessor(state.plan, subContext, manager, this.dataMgr);
if (currentContext != null) {
state.processor.getContext().pushVariableContext(currentContext);
}
state.collector = state.processor.createBatchCollector();
}
state.done = true;
}
return new DependentValueSource(state.collector.collectTuples()).getValueIterator(ref.getValueExpression());
}