@Override public void visit(OpLeftJoin opLeftJoin) { Element eLeft = asElement(opLeftJoin.getLeft()) ; ElementGroup eRight = asElementGroup(opLeftJoin.getRight()) ; ElementGroup g = currentGroup() ; if ( !emptyGroup(eLeft) ) { if ( eLeft instanceof ElementGroup ) g.getElements().addAll(((ElementGroup)eLeft).getElements()) ;
/** Insert into a group, skip initial empty subgroups; recombining ElementPathBlock */ private static void insertIntoGroup(ElementGroup eg, Element e) { // Skip initial empty subgroup. if ( emptyGroup(e) && eg.isEmpty() ) return ; // Empty group. if ( eg.isEmpty() ) { eg.addElement(e); return ; } Element eltTop = eg.getLast() ; if ( ! ( eltTop instanceof ElementPathBlock ) ) { // Not working on a ElementPathBlock - no need to group-of-one // when inserting ElementPathBlock. e = unwrapGroupOfOnePathBlock(e) ; eg.addElement(e); return ; } if ( ! ( e instanceof ElementPathBlock ) ) { eg.addElement(e); return ; } // Combine. ElementPathBlock currentPathBlock = (ElementPathBlock)eltTop ; ElementPathBlock newPathBlock = (ElementPathBlock)e ; currentPathBlock.getPattern().addAll(newPathBlock.getPattern()); }
@Override public void visit(OpUnion opUnion) { Element eLeft = asElementGroup(opUnion.getLeft()) ; Element eRight = asElementGroup(opUnion.getRight()) ; if ( eLeft instanceof ElementUnion ) { ElementUnion elUnion = (ElementUnion)eLeft ; elUnion.addElement(eRight) ; return ; } // Multiple unions. // if ( eRight instanceof ElementUnion ) // { // ElementUnion elUnion = (ElementUnion)eRight ; // elUnion.getElements().add(0, eLeft) ; // return ; // } ElementUnion elUnion = new ElementUnion() ; elUnion.addElement(eLeft) ; elUnion.addElement(eRight) ; currentGroup().addElement(elUnion) ; }
@Override public void visit(OpQuadPattern quadPattern) { Node graphNode = quadPattern.getGraphNode() ; if ( graphNode.equals(Quad.defaultGraphNodeGenerated) ) { currentGroup().addElement(process(quadPattern.getBasicPattern())) ; } else { startSubGroup() ; Element e = asElement(new OpBGP(quadPattern.getBasicPattern())) ; endSubGroup() ; // If not element group make it one if ( !(e instanceof ElementGroup) ) { ElementGroup g = new ElementGroup() ; g.addElement(e) ; e = g ; } Element graphElt = new ElementNamedGraph(graphNode, e) ; currentGroup().addElement(graphElt) ; } }
@Override public void visit(OpJoin opJoin) { Element eLeft = asElement(opJoin.getLeft()) ; ElementGroup eRightGroup = asElementGroup(opJoin.getRight()) ; Element eRight = eRightGroup ; // Very special case. If the RHS is not something that risks // reparsing into a combined element of a group, strip the group-of-one. // See also ElementTransformCleanGroupsOfOne if ( eRightGroup.size() == 1 ) { // This always was a {} around it but it's unnecessary in a group of one. if ( eRightGroup.get(0) instanceof ElementSubQuery ) eRight = eRightGroup.get(0) ; } ElementGroup g = currentGroup() ; insertIntoGroup(g, eLeft) ; insertIntoGroup(g, eRight) ; return ; }
@Override public void visit(OpSequence opSequence) { ElementGroup g = currentGroup() ; boolean nestGroup = !g.isEmpty() ; if ( nestGroup ) { startSubGroup() ; g = currentGroup() ; } for ( Op op : opSequence.getElements() ) { Element e = asElement(op) ; insertIntoGroup(g, e) ; } if ( nestGroup ) endSubGroup() ; return ; }
private void newLevel(Op op) { convertAsSubQuery(op) ; }
@Override public void visit(OpTable opTable) { // This will go in a group so simply forget it. if ( opTable.isJoinIdentity() ) return ; // Put in a VALUES // This may be related to the grpup of the overall query. ElementData el = new ElementData() ; el.getVars().addAll(opTable.getTable().getVars()) ; QueryIterator qIter = opTable.getTable().iterator(null) ; while (qIter.hasNext()) el.getRows().add(qIter.next()) ; qIter.close() ; currentGroup().addElement(el) ; }
@Override public void visit(OpFilter opFilter) { // (filter .. (filter ( ... )) (non-canonicalizing OpFilters) // Inner gets Grouped unnecessarily. Element e = asElement(opFilter.getSubOp()) ; if ( currentGroup() != e ) currentGroup().addElement(e) ; element = currentGroup() ; // Was cleared by asElement. ExprList exprs = opFilter.getExprs() ; for ( Expr expr : exprs ) { ElementFilter f = new ElementFilter(expr) ; currentGroup().addElement(f) ; } }
@Override public void visit(OpGraph opGraph) { startSubGroup() ; Element e = asElement(opGraph.getSubOp()) ; endSubGroup() ; // If not element group make it one if ( !(e instanceof ElementGroup) ) { ElementGroup g = new ElementGroup() ; g.addElement(e) ; e = g ; } Element graphElt = new ElementNamedGraph(opGraph.getNode(), e) ; currentGroup().addElement(graphElt) ; }
@Override public void visit(OpTriple opTriple) { currentGroup().addElement(process(opTriple.getTriple())) ; }
@Override public void visit(OpBGP opBGP) { currentGroup().addElement(process(opBGP.getPattern())) ; }
private Element asElement(Op op) { ElementGroup g = asElementGroup(op) ; if ( g.size() == 1 ) return g.get(0) ; return g ; }
/** * Process for a single pattern below the modifiers. * Cleans up the ElementGroup produced. */ private void processQueryPattern(QueryLevelDetails level) { Op op = level.pattern ; op.visit(this) ; ElementGroup eg = this.currentGroup ; Element e = fixupGroupsOfOne(eg) ; query.setQueryPattern(e) ; query.setQuerySelectType() ; }
@Override public void visit(OpAssign opAssign) { Element e = asElement(opAssign.getSubOp()) ; // If (assign ... (table unit)), and first in group, don't add the empty group. insertIntoGroup(currentGroup(), e) ; processAssigns(Arrays.asList(opAssign), (var,expr)->{ currentGroup().addElement(new ElementAssign(var,expr)) ; }) ; }
private ElementGroup asElementGroup(Op op) { startSubGroup() ; op.visit(this) ; return endSubGroup() ; }
private void processQueryPattern(Op op, List<OpExtend> assignments) { op.visit(this) ; ElementGroup eg = this.currentGroup ; processExtends(assignments,(v,e)->eg.addElement(new ElementBind(v, e)) ) ; Element e = fixupGroupsOfOne(eg) ; query.setQueryPattern(e) ; query.setQuerySelectType() ; }
@Override public void visit(OpPath opPath) { ElementPathBlock epb = new ElementPathBlock() ; epb.addTriplePath(opPath.getTriplePath()) ; ElementGroup g = currentGroup() ; g.addElement(epb) ; }
Query convert() { if ( !hasRun ) try { // Which may be broken, or null, if something went wrong. query = convertInner() ; } finally { this.hasRun = true ; } return query ; }