@Override public IntermediateQuery transform(IntermediateQuery originalQuery) throws QueryTransformationException { QueryNode rootNode = originalQuery.getRootNode(); ImmutableList<Variable> nullableVariables = extractNullableVariables(originalQuery, rootNode); return nullableVariables.isEmpty() ? originalQuery : insertFilter(originalQuery, nullableVariables); }
/** * If the root is a construction node, inserts the filter below it. * Otherwise inserts it as the root. */ private IntermediateQuery insertFilter(IntermediateQuery originalQuery, ImmutableList<Variable> nullableVariables) { FilterNode filterNode = iQFactory.createFilterNode(computeFilterExpression(nullableVariables)); IntermediateQueryBuilder builder = originalQuery.newBuilder(); QueryNode rootNode = originalQuery.getRootNode(); QueryNode newRoot = rootNode instanceof ConstructionNode ? rootNode : filterNode; QueryNode child = rootNode instanceof ConstructionNode ? filterNode : rootNode; builder.init(originalQuery.getProjectionAtom(), newRoot); builder.addChild(newRoot, child, Optional.empty()); copyChildren(originalQuery, rootNode, builder, child); return builder.build(); }
private void copyChildren(IntermediateQuery sourceQuery, QueryNode sourceParent, IntermediateQueryBuilder builder, QueryNode targetParent) { for (QueryNode child : sourceQuery.getChildren(sourceParent)) { builder.addChild( targetParent, child, sourceQuery.getOptionalPosition( sourceParent, child )); copyChildren(sourceQuery, child, builder, child); } } }
@Override public IQ transform(IQ originalQuery) { IQTree tree = originalQuery.getTree(); ImmutableSet<ImmutableSet<Variable>> nullableGroups = tree.getVariableNullability().getNullableGroups(); return nullableGroups.isEmpty() ? originalQuery : insertFilter(originalQuery, nullableGroups); }
private IQ insertFilter(IQ originalQuery, ImmutableSet<ImmutableSet<Variable>> nullableVariables) { FilterNode filterNode = iQFactory.createFilterNode(computeFilterExpression(nullableVariables)); UnaryIQTree newTree = iQFactory.createUnaryIQTree(filterNode, originalQuery.getTree()); // TODO: normalize it return iQFactory.createIQ(originalQuery.getProjectionAtom(), newTree); } }