use of org.teiid.query.sql.symbol.ScalarSubquery in project teiid by teiid.
the class ODataSQLBuilder method buildAggregateQuery.
private void buildAggregateQuery(DocumentNode node, Query outerQuery, ExpandDocumentNode expandResource, OrderBy expandOrder, Query query, EdmNavigationProperty navigationProperty) throws TeiidException {
Select select = query.getSelect();
Array array = new Array(Object.class, new ArrayList<Expression>(select.getSymbols()));
select.getSymbols().clear();
AggregateSymbol symbol = new AggregateSymbol(AggregateSymbol.Type.ARRAY_AGG.name(), false, array);
select.addSymbol(symbol);
symbol.setOrderBy(expandOrder);
Criteria crit = node.buildJoinCriteria(expandResource, navigationProperty);
if (crit != null) {
query.setCriteria(Criteria.combineCriteria(crit, query.getCriteria()));
}
// else assertion error?
expandResource.setColumnIndex(outerQuery.getSelect().getCount() + 1);
ScalarSubquery agg = new ScalarSubquery(query);
SubqueryHint subqueryHint = new SubqueryHint();
subqueryHint.setMergeJoin(true);
agg.setSubqueryHint(subqueryHint);
outerQuery.getSelect().addSymbol(agg);
}
use of org.teiid.query.sql.symbol.ScalarSubquery in project teiid by teiid.
the class ODataExpressionToSQLVisitor method visit.
// ///////////////////////////////////////////////////////////////////////
// RequestURLHierarchyVisitor specific methods
// ///////////////////////////////////////////////////////////////////////
@Override
public void visit(UriResourcePrimitiveProperty info) {
if (this.root) {
this.stack.add(new ScalarSubquery(buildRootSubQuery(info.getProperty().getName(), this.ctxExpression)));
root = false;
} else {
this.stack.add(new ElementSymbol(info.getProperty().getName(), this.ctxExpression.getGroupSymbol()));
}
// hack to resolve the property type.
Column c = this.ctxExpression.getColumnByName(info.getProperty().getName());
this.lastPropertyType = c.getRuntimeType();
// revert back to the query context
this.ctxExpression = this.ctxQuery;
}
use of org.teiid.query.sql.symbol.ScalarSubquery in project teiid by teiid.
the class SubqueryAwareEvaluator method evaluatePushdown.
/**
* Implements must pushdown function handling if supported by the source.
*
* The basic strategy is to create a dummy subquery to represent the evaluation
*/
@Override
protected Object evaluatePushdown(Function function, List<?> tuple, Object[] values) throws TeiidComponentException, TeiidProcessingException {
final FunctionDescriptor fd = function.getFunctionDescriptor();
if (fd.getMethod() == null) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName()));
}
String schema = null;
if (fd.getMethod().getParent() == null || !fd.getMethod().getParent().isPhysical()) {
// find a suitable target
// TODO: do better than a linear search
VDBMetaData vdb = this.context.getVdb();
CapabilitiesFinder capabiltiesFinder = this.context.getQueryProcessorFactory().getCapabiltiesFinder();
for (ModelMetaData mmd : vdb.getModelMetaDatas().values()) {
if (!mmd.isSource()) {
continue;
}
SourceCapabilities caps = capabiltiesFinder.findCapabilities(mmd.getName());
if (caps.supportsCapability(Capability.SELECT_WITHOUT_FROM) && caps.supportsFunction(fd.getMethod().getFullName())) {
schema = mmd.getName();
break;
}
}
if (schema == null) {
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName()));
}
} else {
if (!CapabilitiesUtil.supports(Capability.SELECT_WITHOUT_FROM, fd.getMethod().getParent(), context.getMetadata(), context.getQueryProcessorFactory().getCapabiltiesFinder())) {
if (elements != null) {
Integer index = (Integer) elements.get(function);
if (index != null) {
return tuple.get(index.intValue());
}
}
throw new FunctionExecutionException(QueryPlugin.Event.TEIID30341, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30341, fd.getFullName()));
}
schema = fd.getSchema();
}
ScalarSubquery ss = null;
if (functionState != null) {
ss = functionState.get(function);
}
Expression[] functionArgs = new Expression[values.length];
for (int i = 0; i < values.length; i++) {
functionArgs[i] = new Constant(values[i]);
}
if (ss == null) {
final Query command = new Query();
Select select = new Select();
command.setSelect(select);
Function f = new Function(function.getName(), functionArgs);
f.setType(function.getType());
f.setFunctionDescriptor(fd);
select.addSymbol(f);
ss = new ScalarSubquery(command);
SymbolMap correlatedReferences = new SymbolMap();
Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(function, true);
if (!elements.isEmpty()) {
for (ElementSymbol es : elements) {
correlatedReferences.addMapping(es, es);
}
command.setCorrelatedReferences(correlatedReferences);
}
command.setProcessorPlan(new SimpleProcessorPlan(command, schema, fd, Arrays.asList(new Constant(null, fd.getReturnType()))));
} else {
((Function) ((ExpressionSymbol) ss.getCommand().getProjectedSymbols().get(0)).getExpression()).setArgs(functionArgs);
}
if (functionState == null) {
this.functionState = new HashMap<Function, ScalarSubquery>(2);
}
functionState.put(function, ss);
return internalEvaluate(ss, tuple);
}
use of org.teiid.query.sql.symbol.ScalarSubquery in project teiid by teiid.
the class RuleRaiseAccess method checkConformedSubqueries.
static boolean checkConformedSubqueries(PlanNode accessNode, PlanNode parentNode, boolean updateConformed) {
Set<Object> conformedSources = (Set<Object>) accessNode.getProperty(Info.CONFORMED_SOURCES);
if (conformedSources == null) {
return true;
}
conformedSources = new HashSet<Object>(conformedSources);
for (SubqueryContainer<?> container : parentNode.getSubqueryContainers()) {
if (container instanceof ExistsCriteria && ((ExistsCriteria) container).shouldEvaluate()) {
continue;
}
if (container instanceof ScalarSubquery && ((ScalarSubquery) container).shouldEvaluate()) {
continue;
}
ProcessorPlan plan = container.getCommand().getProcessorPlan();
if (plan == null) {
continue;
}
AccessNode aNode = CriteriaCapabilityValidatorVisitor.getAccessNode(plan);
if (aNode == null) {
continue;
}
Set<Object> conformedTo = aNode.getConformedTo();
if (conformedTo == null) {
conformedSources.retainAll(Collections.singletonList(aNode.getModelId()));
} else {
conformedSources.retainAll(conformedTo);
}
if (conformedSources.isEmpty()) {
return false;
}
}
if (updateConformed) {
updateConformed(accessNode, conformedSources);
}
return true;
}
use of org.teiid.query.sql.symbol.ScalarSubquery in project teiid by teiid.
the class RuleMergeCriteria method findSubquery.
public PlannedResult findSubquery(Expression expr, boolean unnest, PlannedResult result) {
if (expr instanceof ScalarSubquery) {
ScalarSubquery scc = (ScalarSubquery) expr;
if (scc.getSubqueryHint().isNoUnnest()) {
return result;
}
Query query = (Query) scc.getCommand();
if (!isSingleRow(query)) {
return result;
}
result.type = scc.getClass();
result.mergeJoin = scc.getSubqueryHint().isMergeJoin();
if (!unnest && !result.mergeJoin) {
return result;
}
result.makeInd = scc.getSubqueryHint().isDepJoin();
result.query = query;
}
return result;
}
Aggregations