private ImmutableSet<Variable> getChildProjectedVariables(IntermediateQuery query, Optional<ImmutableSet<Variable>> optionalChildVariables, ArgumentPosition position) { return optionalChildVariables .orElseGet(() -> query.getVariables(query.getChild(this, position) .orElseThrow(() -> new IllegalStateException("Missing child ")))); }
@Override public NodeTransformationProposal reactToEmptyChild(IntermediateQuery query, EmptyNode emptyChild) { return new NodeTransformationProposalImpl(NodeTransformationProposedState.DECLARE_AS_EMPTY, query.getVariables(this)); }
@Override public boolean isVariableNullable(IntermediateQuery query, Variable variable) { QueryNode leftChild = query.getChild(this, LEFT) .orElseThrow(() -> new InvalidIntermediateQueryException("A left child is required")); if (query.getVariables(leftChild).contains(variable)) return leftChild.isVariableNullable(query, variable); QueryNode rightChild = query.getChild(this, RIGHT) .orElseThrow(() -> new InvalidIntermediateQueryException("A right child is required")); if (!query.getVariables(rightChild).contains(variable)) throw new IllegalArgumentException("The variable " + variable + " is not projected by " + this); return false; }
@Override public boolean isVariableNullable(IntermediateQuery query, Variable variable) { QueryNode leftChild = query.getChild(this, LEFT) .orElseThrow(() -> new InvalidIntermediateQueryException("A left child is required")); if (query.getVariables(leftChild).contains(variable)) return leftChild.isVariableNullable(query, variable); QueryNode rightChild = query.getChild(this, RIGHT) .orElseThrow(() -> new InvalidIntermediateQueryException("A right child is required")); if (!query.getVariables(rightChild).contains(variable)) throw new IllegalArgumentException("The variable " + variable + " is not projected by " + this); return false; }
private NodeCentricOptimizationResults<InnerJoinNode> declareSubTreeAsEmpty(IntermediateQuery query, QueryTreeComponent treeComponent, InnerJoinNode topJoinNode) { /* * Replaces by an EmptyNode */ EmptyNode emptyNode = iqFactory.createEmptyNode(query.getVariables(topJoinNode)); treeComponent.replaceSubTree(topJoinNode, emptyNode); /* * If the query is not empty, changes the type of the results */ return new NodeCentricOptimizationResultsImpl<>(query, Optional.of(emptyNode)); }
private void checkExpression(JoinOrFilterNode node, ImmutableExpression expression) { ImmutableSet<Variable> unboundVariables = expression.getVariableStream() .filter(v -> !(query.getChildren(node).stream() .flatMap(c -> query.getVariables(c).stream()) .collect(ImmutableCollectors.toSet()) .contains(v))) .collect(ImmutableCollectors.toSet()); if (!unboundVariables.isEmpty()) { throw new InvalidIntermediateQueryException("Expression " + expression + " of " + expression + " uses unbound variables (" + unboundVariables + ").\n" + query); } }
private void checkExpression(JoinOrFilterNode node, ImmutableExpression expression) { ImmutableSet<Variable> unboundVariables = expression.getVariableStream() .filter(v -> !(query.getChildren(node).stream() .flatMap(c -> query.getVariables(c).stream()) .collect(ImmutableCollectors.toSet()) .contains(v))) .collect(ImmutableCollectors.toSet()); if (!unboundVariables.isEmpty()) { throw new InvalidIntermediateQueryException("Expression " + expression + " of " + expression + " uses unbound variables (" + unboundVariables + ").\n" + query); } }
private ImmutableList<Variable> extractNullableVariables(IntermediateQuery query, QueryNode rootNode) { ImmutableSet<Variable> requiredVariables = rootNode instanceof ConstructionNode ? rootNode.getRequiredVariables(query): query.getVariables(rootNode); return requiredVariables.stream() .filter(v -> rootNode.isVariableNullable(query, v)) .collect(ImmutableCollectors.toList()); }
@Override public ImmutableSet<Variable> getRequiredVariables(IntermediateQuery query) { ImmutableMultiset<Variable> childrenVariableBag = query.getChildren(this).stream() .flatMap(c -> query.getVariables(c).stream()) .collect(ImmutableCollectors.toMultiset()); Stream<Variable> cooccuringVariableStream = childrenVariableBag.entrySet().stream() .filter(e -> e.getCount() > 1) .map(Multiset.Entry::getElement); return Stream.concat(cooccuringVariableStream, getLocallyRequiredVariables().stream()) .collect(ImmutableCollectors.toSet()); }
@Override public ImmutableSet<Variable> getRequiredVariables(IntermediateQuery query) { ImmutableMultiset<Variable> childrenVariableBag = query.getChildren(this).stream() .flatMap(c -> query.getVariables(c).stream()) .collect(ImmutableCollectors.toMultiset()); Stream<Variable> cooccuringVariableStream = childrenVariableBag.entrySet().stream() .filter(e -> e.getCount() > 1) .map(Multiset.Entry::getElement); return Stream.concat(cooccuringVariableStream, getLocallyRequiredVariables().stream()) .collect(ImmutableCollectors.toSet()); } }
private static EmptyNode replaceByEmptyNode(QueryNode rejectedNode, ImmutableSubstitution descendingSubstitution, IntermediateQuery query, Optional<NodeTracker> optionalTracker) { optionalTracker.ifPresent(tr -> tr.recordUpcomingRemoval(query, rejectedNode)); /** * The new set of projected variables have to take into account * the changes proposed by the descending substitution. */ ImmutableSet<Variable> newProjectedVariables = query.getVariables(rejectedNode).stream() .flatMap(v -> descendingSubstitution.apply(v).getVariableStream()) .collect(ImmutableCollectors.toSet()); return query.getFactory().createEmptyNode(newProjectedVariables); }
private boolean isMandatoryRoot(ConstructionNode cn, IntermediateQuery query){ if(cn.equals(query.getRootNode())){ if(!query.getProjectionAtom().getVariables().equals( query.getVariables( query.getChildren(cn).iterator().next() ))){ return true; } } return false; }
@Override public void visit(OrderByNode orderByNode) { if (query.getChildren(orderByNode).size() != 1) { throw new InvalidIntermediateQueryException("ORDER BY node " + orderByNode + " must have ONE and ONLY ONE child.\n" + query); } ImmutableSet<Variable> requiredVariables = orderByNode.getLocallyRequiredVariables(); for (QueryNode child : query.getChildren(orderByNode)) { if (!query.getVariables(child).containsAll(requiredVariables)) { throw new InvalidIntermediateQueryException("Some variables used in the node " + this + " are not provided by its child " + child); } } } }
@Override public void visit(ConstructionNode constructionNode) { if (query.getChildren(constructionNode).size() != 1) { throw new InvalidIntermediateQueryException("CONSTRUCTION node " + constructionNode + " must have ONE and ONLY ONE child.\n" + query); } ImmutableSet<Variable> requiredChildVariables = constructionNode.getChildVariables(); for (QueryNode child : query.getChildren(constructionNode)) { ImmutableSet<Variable> childProjectedVariables = query.getVariables(child); if (!childProjectedVariables.containsAll(requiredChildVariables)) { throw new InvalidIntermediateQueryException("This child " + child + " does not project all the variables " + "required by the CONSTRUCTION node (" + requiredChildVariables + ")\n" + query); } } }
@Override public void visit(UnionNode unionNode) { if (query.getChildren(unionNode).size() < 2) { throw new InvalidIntermediateQueryException("UNION node " + unionNode +" does not have at least 2 children node."); } ImmutableSet<Variable> unionProjectedVariables = unionNode.getVariables(); for (QueryNode child : query.getChildren(unionNode)) { ImmutableSet<Variable> childProjectedVariables = query.getVariables(child); if (!childProjectedVariables.containsAll(unionProjectedVariables)) { throw new InvalidIntermediateQueryException("This child " + child + " does not project all the variables " + "required by the UNION node (" + unionProjectedVariables + ")\n" + query); } } }
@Override public void visit(UnionNode unionNode) { if (query.getChildren(unionNode).size() < 2) { throw new InvalidIntermediateQueryException("UNION node " + unionNode +" does not have at least 2 children node."); } ImmutableSet<Variable> unionProjectedVariables = unionNode.getVariables(); for (QueryNode child : query.getChildren(unionNode)) { ImmutableSet<Variable> childProjectedVariables = query.getVariables(child); if (!childProjectedVariables.containsAll(unionProjectedVariables)) { throw new InvalidIntermediateQueryException("This child " + child + " does not project all the variables " + "required by the UNION node (" + unionProjectedVariables + ")\n" + query); } } }
private void validateProjectedVariables(IntermediateQuery query) throws InvalidIntermediateQueryException { ImmutableSet<Variable> projectedVariables = query.getVariables(query.getRootNode()); if (!projectedVariables.equals(query.getProjectionAtom().getVariables())) { throw new InvalidIntermediateQueryException("The variables projected by the root node" + projectedVariables + " do not match the projection atom " + query.getProjectionAtom()); } } }
private void validateProjectedVariables(IntermediateQuery query) throws InvalidIntermediateQueryException { ImmutableSet<Variable> projectedVariables = query.getVariables(query.getRootNode()); if (!projectedVariables.equals(query.getProjectionAtom().getVariables())) { throw new InvalidIntermediateQueryException("The variables projected by the root node" + projectedVariables + " do not match the projection atom " + query.getProjectionAtom()); } } }
private UnionNode liftUnionNode(UnionLiftProposal proposal, IntermediateQuery query, QueryTreeComponent treeComponent) { QueryNode targetNode = proposal.getTargetNode(); UnionNode focusNode = proposal.getFocusNode(); UnionNode newTopUnionNode = iqFactory.createUnionNode(query.getVariables(targetNode)); IntermediateQuery querySnapshot = query.createSnapshot(); treeComponent.replaceSubTree(targetNode, newTopUnionNode); querySnapshot.getChildren(focusNode) .forEach(c -> appendUnionChildBranch(c, focusNode, targetNode, newTopUnionNode, query, querySnapshot, treeComponent)); return newTopUnionNode; }
private UnionNode liftUnionNode(UnionLiftProposal proposal, IntermediateQuery query, QueryTreeComponent treeComponent) { QueryNode targetNode = proposal.getTargetNode(); UnionNode focusNode = proposal.getFocusNode(); UnionNode newTopUnionNode = iqFactory.createUnionNode(query.getVariables(targetNode)); IntermediateQuery querySnapshot = query.createSnapshot(); treeComponent.replaceSubTree(targetNode, newTopUnionNode); querySnapshot.getChildren(focusNode) .forEach(c -> appendUnionChildBranch(c, focusNode, targetNode, newTopUnionNode, query, querySnapshot, treeComponent)); return newTopUnionNode; }