private IQTree trimRootFilter(IQTree tree) { return tree.getRootNode() instanceof FilterNode ? ((UnaryIQTree) tree).getChild() : tree; }
private IQTree trimIdleCn(IQTree tree) { return getIdleCn(tree).isPresent() ? ((UnaryIQTree) tree).getChild() : tree; }
/** * Assumes that ORDER BY is ABOVE the first construction node */ private IQTree getFirstNonQueryModifierTree(IQ query) { // Non-final IQTree iqTree = query.getTree(); while (iqTree.getRootNode() instanceof QueryModifierNode) { iqTree = ((UnaryIQTree) iqTree).getChild(); } return iqTree; }
/** * Move ORDER BY above the highest construction node (required by Datalog) */ private IQ liftOrderBy(IQ iq) { IQTree topNonQueryModifierTree = getFirstNonQueryModifierTree(iq); if ((topNonQueryModifierTree instanceof UnaryIQTree) && (((UnaryIQTree) topNonQueryModifierTree).getChild().getRootNode() instanceof OrderByNode)) { return orderByLifter.liftOrderBy(iq); } return iq; } }
IQTree selectedGrandChild = selectedLiftedChild.getChild();
private ImmutableList<IQ> normalizeIQ(IQ query) { IQTree tree = query.getTree(); while(tree.getRootNode() instanceof QueryModifierNode){ tree = ((UnaryIQTree)tree).getChild(); } return splitRootUnion(tree) .map(t -> enforceRootCn(t, query.getProjectionAtom().getVariables())) .map(t -> iqFactory.createIQ(query.getProjectionAtom(), t)) .collect(ImmutableCollectors.toList()); }
/** * Lifts the construction node above and updates the order comparators */ private IQTree liftChildConstructionNode(ConstructionNode newChildRoot, UnaryIQTree newChild, IQProperties liftedProperties) { UnaryIQTree newOrderByTree = iqFactory.createUnaryIQTree( applySubstitution(newChildRoot.getSubstitution()), newChild.getChild(), liftedProperties); return iqFactory.createUnaryIQTree(newChildRoot, newOrderByTree, liftedProperties); }
.orElseGet(child::getVariables); IQTree grandChild = ((UnaryIQTree) child).getChild();
private ChildLiftingState liftRightChild(ChildLiftingState state, VariableGenerator variableGenerator) { IQTree liftedRightChild = state.rightChild.liftBinding(variableGenerator); if (!(liftedRightChild.getRootNode() instanceof ConstructionNode)) { if (state.rightChild.equals(liftedRightChild)) return state; return new ChildLiftingState(state.leftChild, liftedRightChild, state.ljCondition.filter(c -> !liftedRightChild.isDeclaredAsEmpty()), state.ascendingSubstitution); } ConstructionNode rightConstructionNode = (ConstructionNode) liftedRightChild.getRootNode(); IQTree rightGrandChild = ((UnaryIQTree) liftedRightChild).getChild(); ImmutableSubstitution<ImmutableTerm> rightSubstitution = rightConstructionNode.getSubstitution(); return liftRightChild(state, rightGrandChild, rightSubstitution, variableGenerator); }
@Override public IQTree liftBinding(IQTree childIQTree, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newParentTree = propagateDownCondition(childIQTree, Optional.empty()); /* * If after propagating down the condition the root is still a filter node, goes to the next step */ if (newParentTree.getRootNode() instanceof FilterNodeImpl) { return ((FilterNodeImpl)newParentTree.getRootNode()) .liftBindingAfterPropagatingCondition(((UnaryIQTree)newParentTree).getChild(), variableGenerator, currentIQProperties); } else /* * Otherwise, goes back to the general method */ return newParentTree.liftBinding(variableGenerator); }
/** * Projects away variables only for child construction nodes */ private IQTree projectAwayUnnecessaryVariables(IQTree child, IQProperties currentIQProperties) { if (child.getRootNode() instanceof ConstructionNode) { ConstructionNode constructionNode = (ConstructionNode) child.getRootNode(); AscendingSubstitutionNormalization normalization = normalizeAscendingSubstitution( constructionNode.getSubstitution(), projectedVariables); Optional<ConstructionNode> proposedConstructionNode = normalization.generateTopConstructionNode(); if (proposedConstructionNode .filter(c -> c.isSyntacticallyEquivalentTo(constructionNode)) .isPresent()) return child; IQTree grandChild = normalization.normalizeChild(((UnaryIQTree) child).getChild()); return proposedConstructionNode .map(c -> (IQTree) iqFactory.createUnaryIQTree(c, grandChild, currentIQProperties.declareLifted())) .orElse(grandChild); } else return child; }
while ((parentTree.getRootNode() instanceof QueryModifierNode)) { ancestors.push((QueryModifierNode) parentTree.getRootNode()); parentTree = ((UnaryIQTree)parentTree).getChild(); ConstructionNode constructionNode = (ConstructionNode) parentTree.getRootNode(); IQTree childTree = ((UnaryIQTree)parentTree).getChild(); if (childTree.getRootNode() instanceof OrderByNode) { OrderByNode formerOrderByNode = (OrderByNode) childTree.getRootNode(); IQTree grandChildTree = ((UnaryIQTree) childTree).getChild();
private IQTree getProjection(ImmutableSet<Variable> signature, IQTree tree) { QueryNode root = tree.getRootNode(); if (root instanceof ConstructionNode){ return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(signature, ((ConstructionNode)root).getSubstitution()), ((UnaryIQTree)tree).getChild() ); } return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(signature), tree ); } }
IQTree grandChildIQTree = liftedChildIQ.getChild();
private IQTree liftBinding(ConstructionNode childConstructionNode, UnaryIQTree childIQ, IQProperties currentIQProperties) { AscendingSubstitutionNormalization ascendingNormalization = normalizeAscendingSubstitution( childConstructionNode.getSubstitution().composeWith(substitution), projectedVariables); ImmutableSubstitution<ImmutableTerm> newSubstitution = ascendingNormalization.getAscendingSubstitution(); IQTree grandChildIQTree = ascendingNormalization.normalizeChild(childIQ.getChild()); ConstructionNode newConstructionNode = iqFactory.createConstructionNode(projectedVariables, newSubstitution); return iqFactory.createUnaryIQTree(newConstructionNode, grandChildIQTree, currentIQProperties.declareLifted()); }
@Override public IQTree liftBinding(IQTree child, VariableGenerator variableGenerator, IQProperties currentIQProperties) { IQTree newChild = child.liftBinding(variableGenerator); QueryNode newChildRoot = newChild.getRootNode(); IQProperties liftedProperties = currentIQProperties.declareLifted(); if (newChildRoot instanceof ConstructionNode) return liftChildConstructionNode((ConstructionNode) newChildRoot, (UnaryIQTree) newChild, liftedProperties); else if (newChildRoot instanceof EmptyNode) return newChild; else if (newChildRoot instanceof DistinctNode) { return iqFactory.createUnaryIQTree( (DistinctNode) newChildRoot, iqFactory.createUnaryIQTree(this, ((UnaryIQTree)newChild).getChild(), liftedProperties), liftedProperties); } else return iqFactory.createUnaryIQTree(this, newChild, liftedProperties); }
/** * TODO: find a better name */ private IQTree updateChild(UnaryIQTree liftedChildTree, ImmutableSubstitution<ImmutableTerm> mergedSubstitution, ImmutableSet<Variable> projectedVariables) { ConstructionNode constructionNode = (ConstructionNode) liftedChildTree.getRootNode(); ConstructionNodeTools.NewSubstitutionPair substitutionPair = constructionTools.traverseConstructionNode( mergedSubstitution, constructionNode.getSubstitution(), constructionNode.getVariables(), projectedVariables); // NB: this is expected to be ok given that the expected compatibility of the merged substitution with // this construction node ImmutableSubstitution<? extends VariableOrGroundTerm> descendingSubstitution = substitutionFactory.getSubstitution( (ImmutableMap<Variable, ? extends VariableOrGroundTerm>)(ImmutableMap<Variable, ?>) substitutionPair.propagatedSubstitution.getImmutableMap()); IQTree newChild = liftedChildTree.getChild() .applyDescendingSubstitution(descendingSubstitution, Optional.empty()); ConstructionNode newConstructionNode = iqFactory.createConstructionNode(projectedVariables, substitutionPair.bindings); return substitutionPair.bindings.isEmpty() ? newChild : iqFactory.createUnaryIQTree(newConstructionNode, newChild); }
private ChildLiftingState liftLeftChild(IQTree liftedLeftChild, IQTree rightChild, Optional<ImmutableExpression> ljCondition, VariableGenerator variableGenerator) { if (liftedLeftChild.getRootNode() instanceof ConstructionNode) { ConstructionNode leftConstructionNode = (ConstructionNode) liftedLeftChild.getRootNode(); IQTree leftGrandChild = ((UnaryIQTree) liftedLeftChild).getChild(); try { return liftRegularChildBinding(leftConstructionNode, 0, leftGrandChild, ImmutableList.of(liftedLeftChild,rightChild), leftGrandChild.getVariables(), ljCondition, variableGenerator, this::convertIntoChildLiftingResults); } /* * Replaces the LJ by the left child */ catch (UnsatisfiableConditionException e) { EmptyNode newRightChild = iqFactory.createEmptyNode(rightChild.getVariables()); return new ChildLiftingState(leftGrandChild, newRightChild, Optional.empty(), leftConstructionNode.getSubstitution()); } } else if (liftedLeftChild.isDeclaredAsEmpty()) return new ChildLiftingState(liftedLeftChild, iqFactory.createEmptyNode(rightChild.getVariables()), Optional.empty(), substitutionFactory.getSubstitution()); else return new ChildLiftingState(liftedLeftChild, rightChild, ljCondition, substitutionFactory.getSubstitution()); }
private IQTree enforceRootCn(IQTree tree, ImmutableSet<Variable> projectedVariables) { if (tree.getRootNode() instanceof ConstructionNode) { ConstructionNode currentRootNode = (ConstructionNode) tree.getRootNode(); if (currentRootNode.getVariables().equals(projectedVariables)) return tree; ConstructionNode newRootNode = iqFactory.createConstructionNode(projectedVariables, currentRootNode.getSubstitution() .reduceDomainToIntersectionWith(projectedVariables)); return iqFactory.createUnaryIQTree(newRootNode, ((UnaryIQTree) tree).getChild()); } else return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(projectedVariables), tree); }