private void validateProjectedVariables() throws InvalidIntermediateQueryException { ImmutableSet<Variable> projectedVariables = tree.getVariables(); if (!projectedVariables.equals(projectionAtom.getVariables())) { throw new InvalidIntermediateQueryException("The variables projected by the root node" + projectedVariables + " do not match the projection atom " + projectionAtom.getVariables()); } }
@Override public void init(DistinctVariableOnlyDataAtom projectionAtom, QueryNode rootNode){ if (tree != null) throw new IllegalArgumentException("Already initialized IntermediateQueryBuilder."); if ((rootNode instanceof ExplicitVariableProjectionNode) && !projectionAtom.getVariables().equals(((ExplicitVariableProjectionNode)rootNode).getVariables())) { throw new IllegalArgumentException("The root node " + rootNode + " is not consistent with the projection atom " + projectionAtom); } // TODO: use Guice to construct this tree tree = new DefaultTree(rootNode); this.projectionAtom = projectionAtom; canEdit = true; }
@Override public void init(DistinctVariableOnlyDataAtom projectionAtom, QueryNode rootNode){ if (tree != null) throw new IllegalArgumentException("Already initialized IntermediateQueryBuilder."); if ((rootNode instanceof ExplicitVariableProjectionNode) && !projectionAtom.getVariables().equals(((ExplicitVariableProjectionNode)rootNode).getVariables())) { throw new IllegalArgumentException("The root node " + rootNode + " is not consistent with the projection atom " + projectionAtom); } // TODO: use Guice to construct this tree tree = new DefaultTree(rootNode); this.projectionAtom = projectionAtom; canEdit = true; }
/** * Normalizes the input substitution so as to avoid projected variables to be renamed into variables * that are NOT PROJECTED by the closest ExplicitVariableProjectionNode. * * Such an ancestor BLOCKS ascending substitutions and may thus be forced to incorporate some bindings * of the substitution (if it is a ConstructionNode) or to insert a construction node out of a fragment * of the substitution (if it is a UnionNode). * * Without this normalization, blocking the substitution could cause the insertion of illegal bindings * (projected variable to non-projected variable) into a construction node, producing an invalid IQ. * * An alternative solution to normalization would have been to let the ancestors push down a renaming * substitution, but this complicates the substitution propagation mechanisms. * */ private ImmutableSubstitution<? extends ImmutableTerm> normalizeInputSubstitution( N originalFocusNode, IntermediateQuery query, ImmutableSubstitution<? extends ImmutableTerm> substitution) { if (query.getRootNode() == originalFocusNode) return substitution; ImmutableSet<Variable> priorityVariables = query.getAncestors(originalFocusNode).stream() .filter(a -> a instanceof ExplicitVariableProjectionNode) .map(a -> (ExplicitVariableProjectionNode) a) .findFirst() .map(ExplicitVariableProjectionNode::getVariables) .orElseGet(() -> query.getProjectionAtom().getVariables()); return ImmutableSubstitutionTools.prioritizeRenaming(substitution, priorityVariables); }
private static void insertRootConstructionNode(IntermediateQuery query, QueryTreeComponent treeComponent, ImmutableSubstitution<? extends ImmutableTerm> propagatedSubstitution, IntermediateQueryFactory iqFactory) { ImmutableSet<Variable> projectedVariables = query.getProjectionAtom().getVariables(); ImmutableMap<Variable, ImmutableTerm> newSubstitutionMap = propagatedSubstitution.getImmutableMap().entrySet().stream() .filter(e -> projectedVariables.contains(e.getKey())) .collect(ImmutableCollectors.toMap( Map.Entry::getKey, e -> (ImmutableTerm) e.getValue())); ConstructionNode newRootNode = iqFactory.createConstructionNode(projectedVariables, SUBSTITUTION_FACTORY.getSubstitution(newSubstitutionMap)); treeComponent.insertParent(treeComponent.getRootNode(), newRootNode); }
@Override public IntermediateQuery optimize(IntermediateQuery query) { /* Contains all (non discarded) variables projected out by some node previously traversed, plus all variables appearing in an (explicit or implicit) condition of some join node already traversed Immutable only for safety (updated in practice). Question: shall we keep it as immutable ? */ return optimizeSubtree( query.getRootNode(), query, query.getProjectionAtom().getVariables()); }
@Override public IntermediateQuery transform(IntermediateQuery query) throws NotFilterableNullVariableException { QueryNode rootNode = query.getRootNode(); ImmutableList<Variable> nullableProjectedVariables = query.getProjectionAtom().getVariables().stream() .filter(v -> rootNode.isVariableNullable(query, v)) .collect(ImmutableCollectors.toList()); if (nullableProjectedVariables.isEmpty()) return query; ImmutableExpression filterCondition = extractFilteringCondition(query, rootNode, nullableProjectedVariables); return constructQuery(query, rootNode, filterCondition); }
@Override public IntermediateQuery transform(IntermediateQuery query) throws NotFilterableNullVariableException { QueryNode rootNode = query.getRootNode(); ImmutableList<Variable> nullableProjectedVariables = query.getProjectionAtom().getVariables().stream() .filter(v -> rootNode.isVariableNullable(query, v)) .collect(ImmutableCollectors.toList()); if (nullableProjectedVariables.isEmpty()) return query; ImmutableExpression filterCondition = extractFilteringCondition(query, rootNode, nullableProjectedVariables); return constructQuery(query, rootNode, filterCondition); }
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; }
private IQTree getIntensionalCanonizedTree(IQ assertion, DistinctVariableOnlyDataAtom projAtom, IntensionalDataNode intensionalDataNode) { return iqFactory.createUnaryIQTree( iqFactory.createConstructionNode(projAtom.getVariables()), iqFactory.createNaryIQTree( iqFactory.createInnerJoinNode(), ImmutableList.of( assertion.getTree(), intensionalDataNode ))); }
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()); }
.collect(ImmutableCollectors.toList()); IQTree unionTree = iqFactory.createNaryIQTree(iqFactory.createUnionNode(projectionAtom.getVariables()), unionChildren);
ConstructionNode rootNode = iqFactory.createConstructionNode(projectionAtom.getVariables(), new NeutralSubstitution(), optionalTopModifiers); queryBuilder.init(projectionAtom, rootNode); UnionNode unionNode = iqFactory.createUnionNode(projectionAtom.getVariables()); queryBuilder.addChild(rootNode, unionNode);
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()); } } }
/** * TODO: describe */ public IQ convertDatalogRule(CQIE datalogRule, Collection<Predicate> tablePredicates, Optional<ImmutableQueryModifiers> optionalModifiers, IntermediateQueryFactory iqFactory) throws DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException { TargetAtom targetAtom = datalogConversionTools.convertFromDatalogDataAtom(datalogRule.getHead()); DistinctVariableOnlyDataAtom projectionAtom = targetAtom.getProjectionAtom(); ConstructionNode topConstructionNode = iqFactory.createConstructionNode(projectionAtom.getVariables(), targetAtom.getSubstitution()); List<Function> bodyAtoms = List.iterableList(datalogRule.getBody()); if (bodyAtoms.isEmpty()) { return createFact(topConstructionNode, optionalModifiers, projectionAtom, iqFactory); } else { return createDefinition(topConstructionNode, optionalModifiers, projectionAtom, tablePredicates, bodyAtoms, iqFactory); } }
/** * TODO: describe */ public static IntermediateQuery convertDatalogRule(DBMetadata dbMetadata, CQIE datalogRule, Collection<Predicate> tablePredicates, Optional<ImmutableQueryModifiers> optionalModifiers, IntermediateQueryFactory iqFactory, ExecutorRegistry executorRegistry) throws DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException { TargetAtom targetAtom = DatalogConversionTools.convertFromDatalogDataAtom(datalogRule.getHead()); DistinctVariableOnlyDataAtom projectionAtom = targetAtom.getProjectionAtom(); ConstructionNode rootNode = iqFactory.createConstructionNode(projectionAtom.getVariables(), targetAtom.getSubstitution(), optionalModifiers); List<Function> bodyAtoms = List.iterableList(datalogRule.getBody()); if (bodyAtoms.isEmpty()) { return createFact(dbMetadata, rootNode, projectionAtom, executorRegistry, iqFactory); } else { AtomClassification atomClassification = new AtomClassification(bodyAtoms); return createDefinition(dbMetadata, rootNode, projectionAtom, tablePredicates, atomClassification.dataAndCompositeAtoms, atomClassification.booleanAtoms, atomClassification.optionalGroupAtom, iqFactory, executorRegistry); } }