protected static ImmutableMultimap<AtomPredicate, DataNode> extractDataNodes(ImmutableList<QueryNode> siblings) { ImmutableMultimap.Builder<AtomPredicate, DataNode> mapBuilder = ImmutableMultimap.builder(); for (QueryNode node : siblings) { if (node instanceof DataNode) { DataNode dataNode = (DataNode) node; mapBuilder.put(dataNode.getProjectionAtom().getPredicate(), dataNode); } } return mapBuilder.build(); }
private IQTree transformDataNode(DataNode dn) { ImmutableList<Optional<Variable>> replacementVars = getArgumentReplacement(dn); if (empt(replacementVars)) return dn; FilterNode filter = createFilter(dn.getProjectionAtom(), replacementVars); DataAtom atom = replaceVars(dn.getProjectionAtom(), replacementVars); return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(dn.getVariables()), iqFactory.createUnaryIQTree( filter, dn.newAtom(atom)) ); }
protected static <T extends DataNode> SubstitutionResults<T> applySubstitution( T dataNode, ImmutableSubstitution<? extends ImmutableTerm> substitution) { DataAtom newAtom = substitution.applyToDataAtom(dataNode.getProjectionAtom()); T newNode = (T) dataNode.newAtom(newAtom); return DefaultSubstitutionResults.newNode(newNode, substitution); }
/** * TODO: explain */ private FocusNodeUpdate generateUpdate4DataNode(DataNode originalDataNode, ImmutableMap<Integer, VariableRenaming> renamingMap) { DataAtom newAtom = generateNewStandardDataAtom(originalDataNode, renamingMap); DataNode newDataNode = originalDataNode.newAtom(newAtom); return new FocusNodeUpdate(newDataNode, Optional.<InjectiveVar2VarSubstitution>empty(), convertIntoEqualities(renamingMap)); }
DataNode newRightChild = rightChild.newAtom(localSubstitution.applyToDataAtom(rightChild.getProjectionAtom())); treeComponent.replaceNode(rightChild, newRightChild);
/** * dataNodes and UC positions are given for the same predicate * TODO: explain */ private static ImmutableMultimap<ImmutableList<VariableOrGroundTerm>, DataNode> groupByUniqueConstraintArguments( ImmutableCollection<DataNode> dataNodes, ImmutableCollection<ImmutableList<Integer>> collectionOfUCPositions) { ImmutableMultimap.Builder<ImmutableList<VariableOrGroundTerm>, DataNode> groupingMapBuilder = ImmutableMultimap.builder(); for (ImmutableList<Integer> primaryKeyPositions : collectionOfUCPositions) { for (DataNode dataNode : dataNodes) { groupingMapBuilder.put(extractArguments(dataNode.getProjectionAtom(), primaryKeyPositions), dataNode); } } return groupingMapBuilder.build(); } }
VariableGenerator variableGenerator) { ImmutableSet<Variable> leftVariables = leftDataNodes.stream() .flatMap(n -> n.getVariables().stream()) .collect(ImmutableCollectors.toSet()); .collect(ImmutableCollectors.toMultimap()); DataAtom rightProjectionAtom = rightDataNode.getProjectionAtom(); ImmutableList<? extends VariableOrGroundTerm> rightArguments = rightProjectionAtom.getArguments(); DataNode newRightDataNode = rightDataNode.newAtom(computeNewRightAtom(rightProjectionAtom.getPredicate(), rightArguments, conflictingRightArgumentIndexes, variableGenerator)); ImmutableExpression newExpression = computeExpression(rightArguments, newRightDataNode.getProjectionAtom().getArguments());
DataNode newRightChild = rightChild.newAtom(localSubstitution.applyToDataAtom(rightChild.getProjectionAtom())); treeComponent.replaceNode(rightChild, newRightChild);
/** * TODO: explain */ private boolean isRemovable(DataNode node, ImmutableSet<Integer> independentIndexes, ImmutableSet<Variable> requiredAndCooccuringVariables) { ImmutableList<? extends VariableOrGroundTerm> arguments = node.getProjectionAtom().getArguments(); return independentIndexes.stream() .map(i -> arguments.get(i - 1)) .allMatch(t -> (t instanceof Variable) && (!requiredAndCooccuringVariables.contains(t))); }
private Collection<ImmutableSubstitution<VariableOrGroundTerm>> extractDependentUnifiersFromCluster( ImmutableList<Integer> dependentIndexes, Collection<DataNode> cluster, ImmutableSet<DataNode> nodesToRemove, ImmutableSet<Integer> nullableIndexes) throws AtomUnificationException { if (cluster.size() < 2) return ImmutableList.of(); DataNode referenceDataNode = cluster.stream() // Try to get the first kept data node .filter(n -> !nodesToRemove.contains(n)) .findFirst() // Otherwise if all the nodes will be removed, take the first one .orElseGet(() -> cluster.iterator().next()); /* * Ignores the reference data node * * NB: while loop due to the exception */ Collection<ImmutableSubstitution<VariableOrGroundTerm>> substitutionCollection = new ArrayList<>(); for (DataNode currentDataNode : cluster) { if (currentDataNode == referenceDataNode) continue; boolean willBeRemoved = nodesToRemove.contains(currentDataNode); unifyDependentTerms(referenceDataNode.getProjectionAtom(), currentDataNode.getProjectionAtom(), dependentIndexes, willBeRemoved, nullableIndexes) .ifPresent(substitutionCollection::add); } return substitutionCollection; }
private ImmutableList<Optional<Variable>> getArgumentReplacement(DataNode dn) { Set<Variable> vars = new HashSet<>(); List<Optional<Variable>> replacements = new ArrayList<>(); for (VariableOrGroundTerm term: (ImmutableList<VariableOrGroundTerm>) dn.getProjectionAtom().getArguments()) { if (term instanceof GroundTerm) { replacements.add(Optional.of(variableGenerator.generateNewVariable())); } else if (term instanceof Variable) { Variable var = (Variable) term; if (vars.contains(var)) { replacements.add(Optional.of(variableGenerator.generateNewVariableFromVar(var))); } else { replacements.add(Optional.empty()); vars.add(var); } } } return ImmutableList.copyOf(replacements); }
private Optional<GroundTermRemovalFromDataNodeProposal> makeProposal(IntermediateQuery query) { ImmutableList.Builder<DataNode> dataNodesToSimplifyBuilder = ImmutableList.builder(); for (QueryNode node : query.getNodesInTopDownOrder()) { if (node instanceof DataNode) { DataNode dataNode = (DataNode) node; if (dataNode.getProjectionAtom().containsGroundTerms()) { dataNodesToSimplifyBuilder.add(dataNode); } } } ImmutableList<DataNode> dataNodesToSimplify = dataNodesToSimplifyBuilder.build(); if (dataNodesToSimplify.isEmpty()) { return Optional.empty(); } else { GroundTermRemovalFromDataNodeProposal proposal = new GroundTermRemovalFromDataNodeProposalImpl( dataNodesToSimplify); return Optional.of(proposal); } }
protected static ImmutableSubstitution<VariableOrGroundTerm> unifyRedundantNodes( Collection<DataNode> redundantNodes) throws AtomUnificationException { // Non-final ImmutableSubstitution<VariableOrGroundTerm> accumulatedSubstitution = SUBSTITUTION_FACTORY.getSubstitution(); /* * Should normally not be called in this case. */ if (redundantNodes.size() < 2) { // Empty substitution return accumulatedSubstitution; } Iterator<DataNode> nodeIterator = redundantNodes.iterator(); // Non-final DataAtom accumulatedAtom = nodeIterator.next().getProjectionAtom(); while (nodeIterator.hasNext()) { DataAtom newAtom = nodeIterator.next().getProjectionAtom(); // May throw an exception accumulatedSubstitution = updateSubstitution(accumulatedSubstitution, accumulatedAtom, newAtom); accumulatedAtom = accumulatedSubstitution.applyToDataAtom(accumulatedAtom); } return accumulatedSubstitution; }
/** * TODO: explain */ private DataAtom generateNewStandardDataAtom(DataNode originalFocusNode, ImmutableMap<Integer, VariableRenaming> renamingMap) { DataAtom formerAtom = originalFocusNode.getProjectionAtom(); ImmutableList<? extends VariableOrGroundTerm> formerArguments = formerAtom.getArguments(); ImmutableList.Builder<VariableOrGroundTerm> newArgumentBuilder = ImmutableList.builder(); for (int i = 0; i < formerArguments.size(); i++) { if (renamingMap.containsKey(i)) { VariableRenaming variableRenaming = renamingMap.get(i); newArgumentBuilder.add(variableRenaming.newVariable); } else { newArgumentBuilder.add(formerArguments.get(i)); } } return ATOM_FACTORY.getDataAtom(formerAtom.getPredicate(), newArgumentBuilder.build()); }
/** * Predicates not having a DatabaseRelationDefinition are ignored */ private ImmutableMultimap<DatabaseRelationDefinition, DataNode> extractDataNodeMap(IntermediateQuery query, InnerJoinNode joinNode) { DBMetadata dbMetadata = query.getDBMetadata(); return query.getChildren(joinNode).stream() .filter(c -> c instanceof DataNode) .map(c -> (DataNode) c) .map(c -> getDatabaseRelationByName(dbMetadata, c.getProjectionAtom().getPredicate()) .map(r -> new SimpleEntry<DatabaseRelationDefinition, DataNode>(r, c))) .filter(Optional::isPresent) .map(Optional::get) .collect(ImmutableCollectors.toMultimap()); }
/** * * TODO: explain */ private boolean areMatching(DataNode sourceDataNode, DataNode targetDataNode, ForeignKeyConstraint constraint) { ImmutableList<? extends VariableOrGroundTerm> sourceArguments = sourceDataNode.getProjectionAtom().getArguments(); ImmutableList<? extends VariableOrGroundTerm> targetArguments = targetDataNode.getProjectionAtom().getArguments(); return constraint.getComponents().stream() .allMatch(c -> sourceArguments.get(c.getAttribute().getIndex() - 1) .equals(targetArguments.get(c.getReference().getIndex() - 1))); }
ImmutableList.Builder<Integer> variableIndexListBuilder = ImmutableList.builder(); DataAtom dataAtom = dataNode.getProjectionAtom(); ImmutableList<? extends VariableOrGroundTerm> arguments = dataAtom.getArguments();
protected DataNode generateDataNode(DataNode formerDataNode, ImmutableList<VariableOrGroundTerm> arguments) { DataAtom dataAtom = ATOM_FACTORY.getDataAtom(formerDataNode.getProjectionAtom().getPredicate(), arguments); if (formerDataNode instanceof ExtensionalDataNode) { return iqFactory.createExtensionalDataNode(dataAtom); } else if (formerDataNode instanceof IntensionalDataNode) { return iqFactory.createIntensionalDataNode(dataAtom); } else { throw new RuntimeException("Transformation of a data node of type " + formerDataNode.getClass() + " is not supported yet"); } }
private ImmutableCollection<Collection<DataNode>> groupDataNodesPerConstraint( FunctionalDependency constraint, ImmutableCollection<DataNode> initialNodes) { ImmutableList<Integer> constraintDeterminantIndexes = constraint.getDeterminants().stream() .map(Attribute::getIndex) .collect(ImmutableCollectors.toList()); ImmutableMultimap<ImmutableList<VariableOrGroundTerm>, DataNode> nodeMultiMap = initialNodes.stream() .collect(ImmutableCollectors.toMultimap( n -> extractDeterminantArguments(n.getProjectionAtom(), constraintDeterminantIndexes), n -> n)); return nodeMultiMap.asMap().values(); }
/** * TODO: explain */ private ImmutableMap<Integer, VariableRenaming> generateRenamingMap(DataNode focusNode, ImmutableList<Integer> indexes, IntermediateQuery query) throws InvalidQueryOptimizationProposalException { ImmutableMap.Builder<Integer, VariableRenaming> mapBuilder = ImmutableMap.builder(); ImmutableList<? extends VariableOrGroundTerm> arguments = focusNode.getProjectionAtom().getArguments(); for (Integer index : indexes) { VariableOrGroundTerm argument = arguments.get(index); if (argument instanceof Variable) { Variable formerVariable = (Variable) argument; Variable newVariable = query.generateNewVariable(formerVariable); mapBuilder.put(index, new VariableRenaming(formerVariable, newVariable)); } else { throw new InvalidQueryOptimizationProposalException("The argument at the index "+ index + " is not a variable!"); } } return mapBuilder.build(); }