Skip to content

Commit

Permalink
Merge pull request #1631 from afs/lateral
Browse files Browse the repository at this point in the history
GH-1615: LATERAL join
  • Loading branch information
afs authored Dec 1, 2022
2 parents 63ad1a7 + 2ca204e commit 800e865
Show file tree
Hide file tree
Showing 131 changed files with 4,696 additions and 4,256 deletions.
9 changes: 9 additions & 0 deletions jena-arq/Grammar/arq.jj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import org.apache.jena.sparql.expr.aggregate.lib.* ;
import org.apache.jena.update.* ;
import org.apache.jena.sparql.modify.request.* ;
import org.apache.jena.sparql.core.Quad ;
import java.util.List;
import java.util.ArrayList;
public class ARQParser extends ARQParserBase
{}
PARSER_END(ARQParser)
Expand Down Expand Up @@ -612,6 +614,8 @@ Element GraphPatternNotTriples() : { Element el = null ; }
el = GroupOrUnionGraphPattern()
|
el = OptionalGraphPattern()
|
el = LateralGraphPattern()
|
el = MinusGraphPattern()
|
Expand All @@ -637,6 +641,10 @@ Element OptionalGraphPattern() : { Element el ; }
{ <OPTIONAL> el = GroupGraphPattern()
{ return new ElementOptional(el) ; }
}
Element LateralGraphPattern() : { Element el ; }
{ <LATERAL> el = GroupGraphPattern()
{ return new ElementLateral(el) ; }
}
Element GraphGraphPattern() : { Element el ; Node n ;}
{
<GRAPH> n = VarOrIri() el = GroupGraphPattern()
Expand Down Expand Up @@ -1783,6 +1791,7 @@ TOKEN [IGNORE_CASE] :
| < SUBJECT: "SUBJECT" >
| < PREDICATE: "PREDICATE" >
| < OBJECT: "OBJECT" >
| < LATERAL: "LATERAL" >
| < EXISTS: "exists" >
| < NOT: "not" >
| < AS: "as" >
Expand Down
15 changes: 14 additions & 1 deletion jena-arq/Grammar/main.jj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ import org.apache.jena.sparql.modify.request.* ;
#endif
#ifdef ARQ
import org.apache.jena.sparql.core.Quad ;
import java.util.List;
import java.util.ArrayList;
#endif

public class CLASS extends PARSERBASE
Expand Down Expand Up @@ -879,6 +881,10 @@ Element GraphPatternNotTriples() : { Element el = null ; }
el = GroupOrUnionGraphPattern()
|
el = OptionalGraphPattern()
#ifdef ARQ
|
el = LateralGraphPattern()
#endif
|
el = MinusGraphPattern()
|
Expand Down Expand Up @@ -910,13 +916,19 @@ Element OptionalGraphPattern() : { Element el ; }
{ return new ElementOptional(el) ; }
}

#ifdef ARQ
Element LateralGraphPattern() : { Element el ; }
{ <LATERAL> el = GroupGraphPattern()
{ return new ElementLateral(el) ; }
}
#endif

Element GraphGraphPattern() : { Element el ; Node n ;}
{
<GRAPH> n = VarOrIri() el = GroupGraphPattern()
{ return new ElementNamedGraph(n, el) ; }
}


Element ServiceGraphPattern() : { Element el ; Node n ; boolean silent = false ; }
{
<SERVICE>
Expand Down Expand Up @@ -2522,6 +2534,7 @@ TOKEN [IGNORE_CASE] :
| < SUBJECT: "SUBJECT" >
| < PREDICATE: "PREDICATE" >
| < OBJECT: "OBJECT" >
| < LATERAL: "LATERAL" >
#endif
| < EXISTS: "exists" >
| < NOT: "not" >
Expand Down
1 change: 1 addition & 0 deletions jena-arq/Grammar/tokens.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
[<GRAPH>] ::= 'GRAPH'
[<UNION>] ::= 'UNION'
[<OPTIONAL>] ::= 'OPTIONAL'
[<LATERAL>] ::= 'LATERAL'
[<BOUND>] ::= 'BOUND'
[<COALESCE>] ::= 'COALESCE'
[<IF>] ::= 'IF'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ protected Op compileOneInGroup(Element elt, Op current, Deque<Op> acc) {
return compileElementOptional(eltOpt, current);
}

if ( elt instanceof ElementLateral ) {
ElementLateral eltLateral = (ElementLateral)elt;
return compileElementLateral(eltLateral, current);
}

if ( elt instanceof ElementMinus ) {
ElementMinus elt2 = (ElementMinus)elt;
Op op = compileElementMinus(current, elt2);
Expand Down Expand Up @@ -397,6 +402,12 @@ protected Op compileElementOptional(ElementOptional eltOpt, Op current) {
return current;
}

protected Op compileElementLateral(ElementLateral eltLateral, Op current) {
Element subElt = eltLateral.getLateralElement();
Op op = compileElement(subElt);
return OpLateral.create(current, op);
}

protected Op compileBasicPattern(BasicPattern pattern) {
return new OpBGP(pattern);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.core.VarExprList ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.Rename;
import org.apache.jena.sparql.expr.* ;
import org.apache.jena.sparql.expr.aggregate.Aggregator ;
import org.apache.jena.sparql.pfunction.PropFuncArg ;
import org.apache.jena.sparql.syntax.* ;
import org.apache.jena.sparql.syntax.syntaxtransform.*;
import org.apache.jena.sparql.syntax.syntaxtransform.ElementTransform;
import org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformCleanGroupsOfOne;
import org.apache.jena.sparql.syntax.syntaxtransform.ElementTransformer;
import org.apache.jena.sparql.syntax.syntaxtransform.ExprTransformApplyElementTransform;
import org.apache.jena.sparql.util.graph.GraphList ;
import org.apache.jena.vocabulary.RDF ;

Expand Down Expand Up @@ -499,7 +503,7 @@ private Node processPropFuncArg(PropFuncArg args) {
}

// There is one special case to consider:
// A path expression was expanded into a OpSequence during Algenra
// A path expression was expanded into a OpSequence during Algebra
// generation. The simple path expressions become an OpSequence that could be
// recombined into an ElementPathBlock.

Expand All @@ -524,7 +528,12 @@ public void visit(OpSequence opSequence) {

@Override
public void visit(OpDisjunction opDisjunction) {
throw new ARQNotImplemented("OpDisjunction") ;
ElementUnion elUnion = new ElementUnion();
for ( Op op : opDisjunction.getElements() ) {
Element el = asElement(op) ;
elUnion.addElement(el);
}
currentGroup().addElement(elUnion) ;
}

private Element process(BasicPattern pattern) {
Expand Down Expand Up @@ -616,8 +625,12 @@ public void visit(OpJoin opJoin) {

@Override
public void visit(OpLeftJoin opLeftJoin) {
Element eLeft = asElement(opLeftJoin.getLeft()) ;
ElementGroup eRight = asElementGroup(opLeftJoin.getRight()) ;
convertLeftJoin(opLeftJoin.getLeft(), opLeftJoin.getRight(), opLeftJoin.getExprs());
}

private void convertLeftJoin(Op opLeft, Op opRight, ExprList exprs) {
Element eLeft = asElement(opLeft) ;
ElementGroup eRight = asElementGroup(opRight) ;

// If the RHS is (filter) we need to protect it from becoming
// part of the expr for the LeftJoin.
Expand All @@ -632,8 +645,8 @@ public void visit(OpLeftJoin opLeftJoin) {
eRight = eRight2 ;
}

if ( opLeftJoin.getExprs() != null ) {
for ( Expr expr : opLeftJoin.getExprs() ) {
if ( exprs != null ) {
for ( Expr expr : exprs ) {
ElementFilter f = new ElementFilter(expr) ;
eRight.addElement(f) ;
}
Expand Down Expand Up @@ -689,9 +702,26 @@ public void visit(OpUnion opUnion) {
currentGroup().addElement(elUnion) ;
}

@Override
public void visit(OpLateral opLateral) {
Element eLeft = asElement(opLateral.getLeft()) ;
ElementGroup eRight = asElementGroup(opLateral.getRight()) ;
ElementGroup g = currentGroup() ;
if ( !emptyGroup(eLeft) ) {
if ( eLeft instanceof ElementGroup )
g.getElements().addAll(((ElementGroup)eLeft).getElements()) ;
else
g.addElement(eLeft) ;
}
ElementLateral eltLateral = new ElementLateral(eRight) ;
g.addElement(eltLateral) ;
}

@Override
public void visit(OpConditional opCondition) {
throw new ARQNotImplemented("OpCondition") ;
// Possibly completely reversing a query exactly because
// there might be filters outside the OpConditional.
convertLeftJoin(opCondition.getLeft(), opCondition.getRight(), null);
}

@Override
Expand Down Expand Up @@ -812,7 +842,10 @@ private void newLevel(Op op) {
}

private void convertAsSubQuery(Op op) {
Converter subConverter = new Converter(op) ;
// Reverse scoped renaming.
// ?/x is illegal so the original query string must have had ?x at this point for any number of "/"
Op op1 = Rename.reverseVarRename(op, true);
Converter subConverter = new Converter(op1) ;
ElementSubQuery subQuery = new ElementSubQuery(subConverter.convert()) ;
ElementGroup g = currentGroup() ;
g.addElement(subQuery) ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public interface OpVisitor
public void visit(OpUnion opUnion) ;
public void visit(OpDiff opDiff) ;
public void visit(OpMinus opMinus) ;
public void visit(OpLateral opLateral) ;
public void visit(OpConditional opCondition) ;

// OpN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public OpVisitorBase() {}

@Override public void visit(OpLeftJoin opLeftJoin) {}

@Override public void visit(OpLateral opLateral) {}

@Override public void visit(OpConditional opCond) {}

@Override public void visit(OpMinus opMinus) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public void visit(OpMinus opMinus)
public void visit(OpUnion opUnion)
{ visit2(opUnion) ; }

@Override public void visit(OpLateral opLateral)
{ visit2(opLateral) ; }

@Override
public void visit(OpConditional opCond)
{ visit2(opCond) ; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public interface Transform
public Op transform(OpDiff opDiff, Op left, Op right) ;
public Op transform(OpMinus opMinus, Op left, Op right) ;
public Op transform(OpUnion opUnion, Op left, Op right) ;
public Op transform(OpLateral opLater, Op left, Op right) ;
public Op transform(OpConditional opCondition, Op left, Op right) ;

// OpN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public class TransformCopy implements Transform
@Override
public Op transform(OpUnion opUnion, Op left, Op right) { return xform(opUnion, left, right) ; }
@Override
public Op transform(OpLateral opLateral, Op left, Op right) { return xform(opLateral, left, right) ; }
@Override
public Op transform(OpConditional opCond, Op left, Op right) { return xform(opCond, left, right) ; }

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

/**
* Special purpose base class for a single transformation.
*
*
* When writing {@link Transform}s to be applied to a tree,
* extend {@link TransformCopy}, not this class.
*/
Expand Down Expand Up @@ -76,6 +76,8 @@ public class TransformSingle implements Transform
@Override
public Op transform(OpUnion opUnion, Op left, Op right) { return opUnion ; }
@Override
public Op transform(OpLateral opCopLateral, Op left, Op right) { return opCopLateral ; }
@Override
public Op transform(OpConditional opCond, Op left, Op right) { return opCond ; }

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public TransformWrapper(Transform transform)
@Override
public Op transform(OpUnion opUnion, Op left, Op right) { return transform.transform(opUnion, left, right) ; }
@Override
public Op transform(OpLateral opLateral, Op left, Op right) { return transform.transform(opLateral, left, right) ; }
@Override
public Op transform(OpConditional opCond, Op left, Op right) { return transform.transform(opCond, left, right) ; }

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@

package org.apache.jena.sparql.algebra.op;

import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.Transform ;
import org.apache.jena.sparql.algebra.Op;
import org.apache.jena.sparql.algebra.Transform;

/** Super class for operators that do not combine other operators */

public abstract class Op0 extends OpBase
{
public abstract Op apply(Transform transform) ;
public abstract Op0 copy() ;
public abstract Op apply(Transform transform);
public abstract Op0 copy();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

package org.apache.jena.sparql.algebra.op;

import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.Transform ;
import org.apache.jena.sparql.algebra.Op;
import org.apache.jena.sparql.algebra.Transform;

/** Super class for operators that operate on a single sub-operation (i.e. a table or sequence))*/

Expand All @@ -29,12 +29,12 @@ public abstract class Op1 extends OpBase

public Op1(Op subOp)
{
this.sub = subOp ;
this.sub = subOp;
}

public Op getSubOp() { return sub ; }
//public void setSubOp(Op op) { sub = op ; }
public Op getSubOp() { return sub; }
//public void setSubOp(Op op) { sub = op; }

public abstract Op apply(Transform transform, Op subOp) ;
public abstract Op1 copy(Op subOp) ;
public abstract Op apply(Transform transform, Op subOp);
public abstract Op1 copy(Op subOp);
}
24 changes: 12 additions & 12 deletions jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/Op2.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,38 @@

package org.apache.jena.sparql.algebra.op;

import org.apache.jena.sparql.algebra.Op ;
import org.apache.jena.sparql.algebra.Transform ;
import org.apache.jena.sparql.util.NodeIsomorphismMap ;
import org.apache.jena.sparql.algebra.Op;
import org.apache.jena.sparql.algebra.Transform;
import org.apache.jena.sparql.util.NodeIsomorphismMap;

/** Super class for operators that combine two sub-operators */

public abstract class Op2 extends OpBase
{
private Op left ;
private Op right ;
private Op left;
private Op right;

public Op2(Op left, Op right)
{
this.left = left ; this.right = right ;
this.left = left; this.right = right;
}

public Op getLeft() { return left ; }
public Op getRight() { return right ; }
public Op getLeft() { return left; }
public Op getRight() { return right; }

public abstract Op apply(Transform transform, Op left, Op right) ;
public abstract Op2 copy(Op left, Op right) ;
public abstract Op apply(Transform transform, Op left, Op right);
public abstract Op2 copy(Op left, Op right);

@Override
public int hashCode()
{
return left.hashCode()<<1 ^ right.hashCode() ^ getName().hashCode() ;
return left.hashCode()<<1 ^ right.hashCode() ^ getName().hashCode();
}

// equalsTo worker
protected final boolean sameArgumentsAs(Op2 op2, NodeIsomorphismMap labelMap)
{
return left.equalTo(op2.left, labelMap) &&
right.equalTo(op2.right, labelMap) ;
right.equalTo(op2.right, labelMap);
}
}
Loading

0 comments on commit 800e865

Please sign in to comment.