@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 ? */ QueryNode rootNode = query.getRootNode(); Optional<QueryNode> rootChild = query.getFirstChild(rootNode); if (rootChild.isPresent()) { return optimizeSubtree( rootChild.get(), query, rootNode.getLocallyRequiredVariables() ); } return query; }
@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()); }
private IntermediateQuery optimizeSubtree(QueryNode focusNode, IntermediateQuery query, ImmutableSet<Variable> retainedVariables) { Optional<ProjectionShrinkingProposal> optionalProposal = Optional.empty(); if (focusNode instanceof UnionNode || focusNode instanceof ConstructionNode) { optionalProposal = makeProposal((ExplicitVariableProjectionNode) focusNode, retainedVariables); } if (focusNode instanceof JoinOrFilterNode) { retainedVariables = updateRetainedVariables((JoinOrFilterNode) focusNode, query, retainedVariables); } else if (focusNode instanceof ConstructionNode) { retainedVariables = updateRetainedVariables((ConstructionNode) focusNode); } if (optionalProposal.isPresent()) { NodeCentricOptimizationResults<ExplicitVariableProjectionNode> optimizationResults; try { optimizationResults = query.applyProposal(optionalProposal.get()); } catch (EmptyQueryException e) { throw new IllegalStateException("The projection shrinker should not empty the query"); } focusNode = optimizationResults.getNewNodeOrReplacingChild().orElseThrow( () -> new IllegalStateException("A replacing node should be generated")); } for (QueryNode childNode : query.getChildren(focusNode)) { query = optimizeSubtree(childNode, query, retainedVariables); } return query; }
private IntermediateQuery optimizeSubtree(QueryNode focusNode, IntermediateQuery query, ImmutableSet<Variable> retainedVariables) { Optional<ProjectionShrinkingProposal> optionalProposal = Optional.empty(); if (focusNode instanceof UnionNode || focusNode instanceof ConstructionNode) { optionalProposal = makeProposal((ExplicitVariableProjectionNode) focusNode, query, retainedVariables); } if (focusNode instanceof JoinOrFilterNode) { retainedVariables = updateRetainedVariables((JoinOrFilterNode) focusNode, query, retainedVariables); } else if (focusNode instanceof ConstructionNode) { retainedVariables = updateRetainedVariables((ConstructionNode) focusNode, query, retainedVariables); } if (optionalProposal.isPresent()) { NodeCentricOptimizationResults<ExplicitVariableProjectionNode> optimizationResults; try { optimizationResults = query.applyProposal(optionalProposal.get()); } catch (EmptyQueryException e) { throw new IllegalStateException("The projection shrinker should not empty the query"); } focusNode = optimizationResults.getNewNodeOrReplacingChild().orElseThrow( () -> new IllegalStateException("A replacing node should be generated")); } for (QueryNode childNode : query.getChildren(focusNode)) { query = optimizeSubtree(childNode, query, retainedVariables); } return query; }