private IQ convertDatalogRule(CQIE datalogRule, ImmutableSet<Predicate> extensionalPredicates) { IQ directlyConvertedIQ = datalogRule2QueryConverter.convertDatalogRule( datalogRule, extensionalPredicates, Optional.empty(), iqFactory); return noNullValueEnforcer.transform(directlyConvertedIQ) .liftBinding(); }
private IQTree convertLeftJoinAtom(List<Function> subAtomsOfTheLJ, Collection<Predicate> tablePredicates, IntermediateQueryFactory iqFactory) throws DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException, IntermediateQueryBuilderException { P2<List<Function>, List<Function>> decomposition = pullOutEqualityNormalizer.splitLeftJoinSubAtoms(subAtomsOfTheLJ); final List<Function> leftAtoms = decomposition._1(); final List<Function> rightAtoms = decomposition._2(); /* * TODO: explain why we just care about the right */ AtomClassification rightSubAtomClassification = new AtomClassification(rightAtoms, datalogTools); Optional<ImmutableExpression> optionalFilterCondition = createFilterExpression( rightSubAtomClassification.booleanAtoms); LeftJoinNode ljNode = iqFactory.createLeftJoinNode(optionalFilterCondition); IQTree leftTree = convertAtoms(leftAtoms, tablePredicates, iqFactory); IQTree rightTree = convertAtoms(rightSubAtomClassification.dataAndCompositeAtoms, tablePredicates, iqFactory); return iqFactory.createBinaryNonCommutativeIQTree(ljNode, leftTree, rightTree); }
private static IntermediateQueryBuilder convertLeftJoinAtom(IntermediateQueryBuilder queryBuilder, QueryNode parentNodeOfTheLJ, List<Function> subAtomsOfTheLJ, Optional<ArgumentPosition> optionalPosition, Collection<Predicate> tablePredicates) throws DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException, IntermediateQueryBuilderException { P2<List<Function>, List<Function>> decomposition = PullOutEqualityNormalizerImpl.splitLeftJoinSubAtoms(subAtomsOfTheLJ); final List<Function> leftAtoms = decomposition._1(); final List<Function> rightAtoms = decomposition._2(); /* * TODO: explain why we just care about the right */ AtomClassification rightSubAtomClassification = new AtomClassification(rightAtoms); Optional<ImmutableExpression> optionalFilterCondition = createFilterExpression( rightSubAtomClassification.booleanAtoms); LeftJoinNode ljNode = queryBuilder.getFactory().createLeftJoinNode(optionalFilterCondition); queryBuilder.addChild(parentNodeOfTheLJ, ljNode, optionalPosition); /* * Adds the left part */ queryBuilder = convertJoinAtom(queryBuilder, ljNode, leftAtoms, LEFT_POSITION, tablePredicates); /* * Adds the right part */ return convertDataOrCompositeAtoms(rightSubAtomClassification.dataAndCompositeAtoms, queryBuilder, ljNode, RIGHT_POSITION, tablePredicates); }
/** * 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); } }
Optional<ImmutableExpression> optionalFilterCondition = createFilterExpression( classification.booleanAtoms); if (optionalFilterCondition.isPresent()) { FilterNode filterNode = iqFactory.createFilterNode(optionalFilterCondition.get()); IQTree childTree = convertDataOrCompositeAtom(classification.dataAndCompositeAtoms.index(0), tablePredicates, iqFactory); return convertDataOrCompositeAtom(classification.dataAndCompositeAtoms.index(0), tablePredicates, iqFactory); .map(a -> convertDataOrCompositeAtom(a, tablePredicates, iqFactory)) .collect(ImmutableCollectors.toList());
Optional<JoinOrFilterNode> optionalFilterOrJoinNode = createFilterOrJoinNode(iqFactory, dataAndCompositeAtoms, booleanAtoms); queryBuilder = convertDataOrCompositeAtoms(dataAndCompositeAtoms, queryBuilder, bottomNode, NO_POSITION, tablePredicates); return queryBuilder.build();
Optional<ImmutableExpression> optionalFilterCondition = createFilterExpression( classification.booleanAtoms); queryBuilder.addChild(parentNodeOfTheJoinNode, filterNode, optionalPosition); return convertDataOrCompositeAtoms(classification.dataAndCompositeAtoms, queryBuilder, filterNode, NO_POSITION, tablePredicates); return convertDataOrCompositeAtoms(classification.dataAndCompositeAtoms, queryBuilder, parentNodeOfTheJoinNode, optionalPosition, tablePredicates); return convertDataOrCompositeAtoms(classification.dataAndCompositeAtoms, queryBuilder, joinNode, NO_POSITION, tablePredicates);
return convertAtoms(subAtoms, tablePredicates, iqFactory); return convertLeftJoinAtom(subAtoms, tablePredicates, iqFactory);
queryBuilder = convertJoinAtom(queryBuilder, parentNode, subAtoms, optionalPosition, tablePredicates); queryBuilder = convertLeftJoinAtom(queryBuilder, parentNode, subAtoms, optionalPosition, tablePredicates);
/** * TODO: explain */ private static Optional<JoinOrFilterNode> createFilterOrJoinNode(IntermediateQueryFactory iqFactory, List<Function> dataAndCompositeAtoms, List<Function> booleanAtoms) { Optional<ImmutableExpression> optionalFilter = createFilterExpression(booleanAtoms); int dataAndCompositeAtomCount = dataAndCompositeAtoms.length(); Optional<JoinOrFilterNode> optionalRootNode; /* * Filter as a root node */ if (optionalFilter.isPresent() && (dataAndCompositeAtomCount == 1)) { optionalRootNode = Optional.of(iqFactory.createFilterNode(optionalFilter.get())); } else if (dataAndCompositeAtomCount > 1) { optionalRootNode = Optional.of(iqFactory.createInnerJoinNode(optionalFilter)); } /* * No need to create a special root node (will be the unique data atom) */ else { optionalRootNode = Optional.empty(); } return optionalRootNode; }
private IQ createDefinition(ConstructionNode topConstructionNode, Optional<ImmutableQueryModifiers> optionalModifiers, DistinctVariableOnlyDataAtom projectionAtom, Collection<Predicate> tablePredicates, List<Function> bodyAtoms, IntermediateQueryFactory iqFactory) throws DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException { try { IQTree bodyTree = convertAtoms(bodyAtoms, tablePredicates, iqFactory); IQTree constructionTree = iqFactory.createUnaryIQTree(topConstructionNode, bodyTree); IQTree tree = optionalModifiers .map(m -> m.insertAbove(constructionTree, iqFactory)) .orElse(constructionTree); return iqFactory.createIQ(projectionAtom, tree); } catch (IntermediateQueryBuilderException e) { throw new DatalogProgram2QueryConverterImpl.InvalidDatalogProgramException(e.getMessage()); } }
/** * 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); } }
@Override public Optional<IQ> convertDatalogDefinitions(Collection<CQIE> atomDefinitions, Collection<Predicate> tablePredicates, Optional<ImmutableQueryModifiers> optionalModifiers) throws InvalidDatalogProgramException { switch(atomDefinitions.size()) { case 0: return Optional.empty(); case 1: CQIE definition = atomDefinitions.iterator().next(); return Optional.of(datalogRuleConverter.convertDatalogRule(definition, tablePredicates, optionalModifiers, iqFactory)); default: List<IQ> convertedDefinitions = new ArrayList<>(); for (CQIE datalogAtomDefinition : atomDefinitions) { convertedDefinitions.add( datalogRuleConverter.convertDatalogRule(datalogAtomDefinition, tablePredicates, Optional.empty(), iqFactory)); } return optionalModifiers.isPresent() ? queryMerger.mergeDefinitions(convertedDefinitions, optionalModifiers.get()) : queryMerger.mergeDefinitions(convertedDefinitions); } }
case 1: CQIE definition = atomDefinitions.iterator().next(); return Optional.of(convertDatalogRule(dbMetadata, definition, tablePredicates, optionalModifiers, iqFactory, executorRegistry)); default: for (CQIE datalogAtomDefinition : atomDefinitions) { convertedDefinitions.add( convertDatalogRule(dbMetadata, datalogAtomDefinition, tablePredicates, Optional.<ImmutableQueryModifiers>empty(), iqFactory, executorRegistry));
@Override public MappingWithProvenance convertMappingRules(ImmutableMap<CQIE, PPMappingAssertionProvenance> datalogMap, DBMetadata dbMetadata, ExecutorRegistry executorRegistry, MappingMetadata mappingMetadata) { ImmutableSet<Predicate> extensionalPredicates = datalogMap.keySet().stream() .flatMap(r -> r.getBody().stream()) .flatMap(Datalog2QueryTools::extractPredicates) .collect(ImmutableCollectors.toSet()); ImmutableMap<IntermediateQuery, PPMappingAssertionProvenance> iqMap = datalogMap.entrySet().stream() .collect(ImmutableCollectors.toMap( e -> Optional.of( convertDatalogRule( dbMetadata, e.getKey(), extensionalPredicates, Optional.empty(), iqFactory, executorRegistry )).map(mappingIQNormalizer::normalize).get(), Map.Entry::getValue )); return provMappingFactory.create(iqMap, mappingMetadata, executorRegistry); } }