private void doRecursiveRewrite(final AST2BOpContext context, final StaticAnalysis sa, final GraphPatternGroup<IGroupMemberNode> group) { final int arity = group.arity(); for (int i = 0; i < arity; i++) { final BOp child = (BOp) group.get(i); if (child instanceof GraphPatternGroup<?>) { // Recursion into groups. doRecursiveRewrite(context, sa, ((GraphPatternGroup<IGroupMemberNode>) child)); } else if (child instanceof SubqueryRoot) { // Recursion into subqueries. final SubqueryRoot subqueryRoot = (SubqueryRoot) child; doRecursiveRewrite(context, sa, subqueryRoot.getWhereClause()); // rewrite the sub-select doSelectQuery(context, sa, (SubqueryBase) child); } else if (child instanceof ServiceNode) { // Do not rewrite things inside of a SERVICE node. continue; } } }
@Override public UnionNode addChild(final JoinGroupNode child) { final JoinGroupNode group = (JoinGroupNode) child; // can only add non-optional join groups as children to union if (group.isOptional()) { log.warn("optional tag on child will be ignored"); } return (UnionNode) super.addChild(child); }
/** * Returns the position in the group. If the node is not present in * the group, the last position in the group is returned. * * We calculate the position in order to make sure that we append * new nodes at the same position of the property path node that * will be replaced later on. This is important in order to keep * semantics of the query, e.g. in the context of OPTIONAL or * MINUS queries we cannot blindly append at the end. See BLZG-1498 * and BLZG-1627 and the respective test cases in TestTickets for * examples that illustrate why this is indeed necessary. */ protected int getPositionOfNodeInGroup( final PropertyPathNode node, final GraphPatternGroup<? extends IGroupMemberNode> group) { final List<? extends IGroupMemberNode> children = group.getChildren(); for (int i=0; i<children.size(); i++) { if (children.get(i).equals(node)) return i; } // if we don't find the property path node, we're in a nested scope // (e.g. for union subgroups). In that case, we append at the end. return children.size(); }
/** * Remove any empty (non-GRAPH) groups (normal groups and UNIONs, but not * GRAPH {}). */ static private void removeEmptyChildGroups(final GraphPatternGroup<?> op) { int n = op.arity(); for (int i = 0; i < n; i++) { final BOp child = op.get(i); if (!(child instanceof GroupNodeBase<?>)) continue; if (((GroupNodeBase<?>) child).getContext() != null) { /* * Do not prune GRAPH ?g {} or GRAPH uri {}. Those constructions * have special semantics. */ continue; } if (child.arity() == 0) { // remove an empty child group. op.removeArg(child); // one less child to visit. n--; } } }
final Set<IVariable<?>> exogenousVars) { final int arity = group.arity(); final BOp child = (BOp) group.get(i); if (childGroup.isOptional() && (!(childGroup.arity() == 1 && childGroup.get(0) instanceof NamedSubqueryInclude))) {
final GraphPatternGroup<?> group) { int arity = group.arity(); final IGroupMemberNode child = (IGroupMemberNode) group.get(i); if(childGroup.isMinus()) { group.addExplainHint(explainHint);
if (graphPattern.args().size() != 1) { return; final BOp potentialStmtPattern = graphPattern.get(0); if (!(potentialStmtPattern instanceof StatementPatternNode)) { return; join.addArg(stmtPattern); selectDistinct.setWhereClause(join); graphPattern.setArg(0, selectDistinct); new StatementPatternNode(stmtPattern); stmtPatternClone.setFastRangeCount(countNodeVar); graphPattern.addArg(stmtPatternClone);
assertEquals(2, astContainer.getOptimizedAST().getWhereClause().arity());
.getWhereClause().get(1);
@Override public void addArg(final int index, final BOp newArg) { assert newArg instanceof JoinGroupNode; super.addArg(index, newArg); }
assertNotNull(queryRoot.getWhereClause().getQueryHint(PipelineOp.Annotations.CHUNK_CAPACITY)); assertNotNull(queryRootSP.getQueryHint(PipelineOp.Annotations.CHUNK_CAPACITY)); assertNotNull(queryRoot.getSlice().getQueryHint(PipelineOp.Annotations.CHUNK_CAPACITY)); assertNotNull(subqueryRoot.getWhereClause().getQueryHint(PipelineOp.Annotations.CHUNK_CAPACITY)); assertNotNull(subqueryRootSP.getQueryHint(PipelineOp.Annotations.CHUNK_CAPACITY)); assertNotNull(subqueryRoot.getSlice().getQueryHint(PipelineOp.Annotations.CHUNK_CAPACITY));
final GraphPatternGroup<?> group) { int arity = group.arity(); final IGroupMemberNode child = (IGroupMemberNode) group.get(i); if(childGroup.isMinus()) { group.addExplainHint(explainHint);
/** * Remove any empty (non-GRAPH) groups (normal groups and UNIONs, but not * GRAPH {}). */ static private void removeEmptyChildGroups(final GraphPatternGroup<?> op) { int n = op.arity(); for (int i = 0; i < n; i++) { final BOp child = op.get(i); if (!(child instanceof GroupNodeBase<?>)) continue; if (((GroupNodeBase<?>) child).getContext() != null) { /* * Do not prune GRAPH ?g {} or GRAPH uri {}. Those constructions * have special semantics. */ continue; } if (child.arity() == 0) { // remove an empty child group. op.removeArg(child); // one less child to visit. n--; } } }
final Set<IVariable<?>> exogenousVars) { final int arity = group.arity(); final BOp child = (BOp) group.get(i); if (childGroup.isOptional() && (!(childGroup.arity() == 1 && childGroup.get(0) instanceof NamedSubqueryInclude))) {
if (graphPattern.args().size() != 1) { return; final BOp potentialStmtPattern = graphPattern.get(0); if (!(potentialStmtPattern instanceof StatementPatternNode)) { return; join.addArg(stmtPattern); selectDistinct.setWhereClause(join); graphPattern.setArg(0, selectDistinct); new StatementPatternNode(stmtPattern); stmtPatternClone.setFastRangeCount(countNodeVar); graphPattern.addArg(stmtPatternClone);
assertEquals(2, astContainer.getOptimizedAST().getWhereClause().arity());
.getWhereClause().get(1);
@Override public void addArg(final BOp newArg) { assert newArg instanceof JoinGroupNode; super.addArg(newArg); }