use of org.teiid.query.sql.LanguageObject in project teiid by teiid.
the class RulePushSelectCriteria method markDependent.
private void markDependent(PlanNode critNode, PlanNode accessNode, QueryMetadataInterface metadata, CapabilitiesFinder capFinder) throws QueryMetadataException, TeiidComponentException {
// once a dependent crit node is pushed, don't bother pushing it further into the command
// dependent access node will use this as an assumption for where dependent sets can appear in the command
critNode.setProperty(NodeConstants.Info.IS_PUSHED, Boolean.TRUE);
if (createdNodes != null) {
// this is during a planning run and should not cause additional side-effects
return;
}
accessNode.setProperty(NodeConstants.Info.IS_DEPENDENT_SET, Boolean.TRUE);
Criteria crit = (Criteria) critNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
if (isMultiAttributeDependentSet(crit)) {
// split the criteria as needed
List<DependentSetCriteria> crits = splitDependentSetCriteria((DependentSetCriteria) crit, CapabilitiesUtil.supports(Capability.ARRAY_TYPE, RuleRaiseAccess.getModelIDFromAccess(accessNode, metadata), metadata, capFinder), metadata);
critNode.setProperty(NodeConstants.Info.SELECT_CRITERIA, new CompoundCriteria(crits));
}
Collection<ElementSymbol> elements = null;
for (PlanNode joinNode : NodeEditor.findAllNodes(accessNode, NodeConstants.Types.JOIN, NodeConstants.Types.SOURCE)) {
List<Criteria> joinCriteria = (List<Criteria>) joinNode.getProperty(Info.JOIN_CRITERIA);
if (joinCriteria == null) {
continue;
}
for (Criteria joinPredicate : joinCriteria) {
if (!(joinPredicate instanceof CompareCriteria)) {
continue;
}
CompareCriteria cc = (CompareCriteria) joinPredicate;
if (!cc.isOptional()) {
continue;
}
if (elements == null) {
elements = ElementCollectorVisitor.getElements((LanguageObject) critNode.getProperty(Info.SELECT_CRITERIA), true);
}
if (!Collections.disjoint(elements, ElementCollectorVisitor.getElements(cc, false))) {
cc.setOptional(false);
}
}
}
}
use of org.teiid.query.sql.LanguageObject in project teiid by teiid.
the class AuthorizationValidationVisitor method validateEntitlements.
/**
* Check that the user is entitled to access all data elements in the command.
*
* @param symbols The collection of <code>Symbol</code>s affected by these actions.
* @param actionCode The actions to validate for
* @param auditContext The {@link AuthorizationService} to use when resource auditing is done.
*/
protected void validateEntitlements(Collection<? extends LanguageObject> symbols, DataPolicy.PermissionType actionCode, Context auditContext) {
Map<String, LanguageObject> nameToSymbolMap = new LinkedHashMap<String, LanguageObject>();
for (LanguageObject symbol : symbols) {
try {
Object metadataID = null;
if (symbol instanceof ElementSymbol) {
metadataID = ((ElementSymbol) symbol).getMetadataID();
if (metadataID instanceof MultiSourceElement || metadataID instanceof TempMetadataID) {
continue;
}
} else if (symbol instanceof GroupSymbol) {
GroupSymbol group = (GroupSymbol) symbol;
metadataID = group.getMetadataID();
if (metadataID instanceof TempMetadataID) {
if (group.isProcedure()) {
Map<String, LanguageObject> procMap = new LinkedHashMap<String, LanguageObject>();
addToNameMap(((TempMetadataID) metadataID).getOriginalMetadataID(), symbol, procMap, getMetadata());
validateEntitlements(PermissionType.EXECUTE, auditContext, procMap);
} else if (group.isTempTable() && group.isImplicitTempGroupSymbol()) {
validateTemp(actionCode, group.getNonCorrelationName(), false, group, auditContext);
}
continue;
}
}
addToNameMap(metadataID, symbol, nameToSymbolMap, getMetadata());
} catch (QueryMetadataException e) {
handleException(e);
} catch (TeiidComponentException e) {
handleException(e);
}
}
validateEntitlements(actionCode, auditContext, nameToSymbolMap);
}
use of org.teiid.query.sql.LanguageObject in project teiid by teiid.
the class AnalysisRecord method addLanaguageObjects.
public static void addLanaguageObjects(PlanNode node, String key, Collection<? extends LanguageObject> objects) {
List<String> values = new ArrayList<String>();
int index = 0;
for (LanguageObject languageObject : objects) {
values.add(languageObject.toString());
List<SubqueryContainer<?>> subqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(languageObject);
for (ListIterator<SubqueryContainer<?>> iterator = subqueries.listIterator(); iterator.hasNext(); ) {
SubqueryContainer<?> subqueryContainer = iterator.next();
// $NON-NLS-1$
node.addProperty(key + " Subplan " + index++, subqueryContainer.getCommand().getProcessorPlan().getDescriptionProperties());
}
}
node.addProperty(key, values);
}
use of org.teiid.query.sql.LanguageObject in project teiid by teiid.
the class RulePlanProcedures method findInputNodes.
private void findInputNodes(final HashSet<ElementSymbol> inputs, PlanNode critNode, final List<Criteria> conjuncts, final Set<ElementSymbol> params) {
while (critNode.getType() == NodeConstants.Types.SELECT) {
final PlanNode currentNode = critNode;
final Criteria crit = (Criteria) currentNode.getProperty(NodeConstants.Info.SELECT_CRITERIA);
critNode = currentNode.getParent();
if (!currentNode.getGroups().isEmpty()) {
continue;
}
LanguageVisitor visitor = new LanguageVisitor() {
public void visit(CompareCriteria compCrit) {
if (compCrit.getOperator() == CompareCriteria.EQ && checkForInput(compCrit.getLeftExpression()) && !checkForAnyInput(compCrit.getRightExpression())) {
addInputNode((Reference) compCrit.getLeftExpression());
}
}
private void addInputNode(Reference param) {
params.add(param.getExpression());
conjuncts.add(crit);
NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
}
public void visit(IsNullCriteria isNull) {
if (!isNull.isNegated() && checkForInput(isNull.getExpression())) {
addInputNode((Reference) isNull.getExpression());
}
}
public void visit(SetCriteria obj) {
if (!obj.isNegated() && checkForInput(obj.getExpression()) && !checkForAnyInput(obj.getValues())) {
addInputNode((Reference) obj.getExpression());
}
}
public void visit(DependentSetCriteria obj) {
if (obj.isNegated()) {
// just a sanity check
return;
}
if (obj.hasMultipleAttributes()) {
for (AttributeComparison comp : obj.getAttributes()) {
if (!checkForInput(comp.dep)) {
return;
}
}
for (AttributeComparison comp : obj.getAttributes()) {
params.add(((Reference) comp.dep).getExpression());
}
conjuncts.add(crit);
NodeEditor.removeChildNode(currentNode.getParent(), currentNode);
} else if (checkForInput(obj.getExpression())) {
addInputNode((Reference) obj.getExpression());
}
}
boolean checkForInput(Expression expr) {
if (!(expr instanceof Reference)) {
return false;
}
// if the expr is a function containing a reference should give a warning
Reference ref = (Reference) expr;
return inputs.contains(ref.getExpression());
}
boolean checkForAnyInput(LanguageObject expr) {
for (Reference ref : ReferenceCollectorVisitor.getReferences(expr)) {
if (checkForInput(ref)) {
return true;
}
}
return false;
}
boolean checkForAnyInput(Collection<Expression> expressions) {
for (Expression expr : expressions) {
if (checkForAnyInput(expr)) {
return true;
}
}
return false;
}
};
for (Criteria conjunct : Criteria.separateCriteriaByAnd(crit)) {
conjunct.acceptVisitor(visitor);
}
}
}
use of org.teiid.query.sql.LanguageObject in project teiid by teiid.
the class RelationalPlanner method assignWithClause.
private void assignWithClause(RelationalNode node, LinkedHashMap<String, WithQueryCommand> pushdownWith, boolean repeated) throws QueryPlannerException, TeiidComponentException {
List<SubqueryContainer<?>> subCommands = new ArrayList<SubqueryContainer<?>>();
if (node instanceof SubqueryAwareRelationalNode) {
for (LanguageObject lo : ((SubqueryAwareRelationalNode) node).getObjects()) {
ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(lo, subCommands);
if (!subCommands.isEmpty()) {
for (SubqueryContainer<?> subquery : subCommands) {
if (subquery.getCommand().getProcessorPlan() instanceof RelationalPlan) {
assignWithClause(((RelationalPlan) subquery.getCommand().getProcessorPlan()).getRootNode(), pushdownWith, repeated | (subquery.getCommand().getCorrelatedReferences() != null && !subquery.getCommand().getCorrelatedReferences().asMap().isEmpty()));
}
}
subCommands.clear();
}
}
}
if (node instanceof PlanExecutionNode) {
// need to check for nested relational plans. these are created by things such as the semi-join optimization in rulemergevirtual
ProcessorPlan plan = ((PlanExecutionNode) node).getProcessorPlan();
if (plan instanceof RelationalPlan) {
// other types of plans will be contained under non-relational plans, which would be out of scope for the parent with
node = ((RelationalPlan) plan).getRootNode();
}
}
if (node instanceof AccessNode) {
AccessNode accessNode = (AccessNode) node;
Map<GroupSymbol, RelationalPlan> subplans = accessNode.getSubPlans();
if (subplans != null) {
for (RelationalPlan subplan : subplans.values()) {
assignWithClause(subplan.getRootNode(), pushdownWith, false);
}
}
Command command = accessNode.getCommand();
if (command instanceof Insert && ((Insert) command).getQueryExpression() != null) {
command = ((Insert) command).getQueryExpression();
}
if (command instanceof QueryCommand) {
if (this.withGroups == null) {
this.withGroups = new TreeSet<GroupSymbol>(nonCorrelatedComparator);
} else {
this.withGroups.clear();
}
GroupCollectorVisitor.getGroupsIgnoreInlineViewsAndEvaluatableSubqueries(command, this.withGroups);
List<WithQueryCommand> with = new ArrayList<WithQueryCommand>();
discoverWith(pushdownWith, command, with, new ArrayList<GroupSymbol>(this.withGroups));
if (!with.isEmpty()) {
List<WithQueryCommand> pushed = new ArrayList<WithQueryCommand>(with);
final Map<GroupSymbol, Integer> order = new HashMap<GroupSymbol, Integer>();
for (WithQueryCommand withQueryCommand : pushdownWith.values()) {
order.put(withQueryCommand.getGroupSymbol(), order.size());
}
Collections.sort(with, new Comparator<WithQueryCommand>() {
@Override
public int compare(WithQueryCommand o1, WithQueryCommand o2) {
return order.get(o1.getGroupSymbol()).compareTo(order.get(o2.getGroupSymbol()));
}
});
// pull up the with from the subqueries
for (int i = 0; i < with.size(); i++) {
WithQueryCommand wqc = with.get(i);
List<WithQueryCommand> with2 = wqc.getCommand().getWith();
if (with2 != null) {
with.addAll(i, with2);
i += with2.size();
wqc.getCommand().setWith(null);
}
}
QueryCommand query = (QueryCommand) command;
List<SubqueryContainer<?>> subqueries = ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(query);
this.withGroups.clear();
for (WithQueryCommand wqc : with) {
withGroups.add(wqc.getGroupSymbol());
}
pullupWith(with, subqueries, withGroups);
if (query.getWith() != null) {
// we need to accumulate as a with clause could have been used at a lower scope
query.getWith().addAll(with);
} else {
query.setWith(with);
}
for (WithQueryCommand wqc : pushed) {
Object o = this.withPlanningState.pushdownState.get(wqc.getGroupSymbol().getName());
if (o == null) {
if (!repeated) {
if (accessNode.info != null) {
o = accessNode.info.id;
} else {
o = Boolean.FALSE;
}
} else {
o = Boolean.TRUE;
}
} else if (o instanceof Integer) {
// check for shared
if (accessNode.info == null || !o.equals(accessNode.info.id)) {
o = Boolean.TRUE;
}
} else {
o = Boolean.TRUE;
}
this.withPlanningState.pushdownState.put(wqc.getGroupSymbol().getName(), o);
}
// TODO: this should be based upon whether any of the need evaluated
accessNode.setShouldEvaluateExpressions(true);
}
}
}
// Recurse through children
RelationalNode[] children = node.getChildren();
for (int i = 0; i < node.getChildCount(); i++) {
assignWithClause(children[i], pushdownWith, repeated);
}
}
Aggregations