Skip to content

Commit

Permalink
GH-2924: Lateral - fixed injection for tables, enhanced QueryExec API…
Browse files Browse the repository at this point in the history
… for easier testing.
  • Loading branch information
Aklakan committed Jan 9, 2025
1 parent 5114670 commit 645968d
Show file tree
Hide file tree
Showing 25 changed files with 253 additions and 50 deletions.
6 changes: 3 additions & 3 deletions jena-arq/src/main/java/org/apache/jena/query/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.apache.jena.atlas.logging.Log ;
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.ARQConstants ;
import org.apache.jena.sparql.algebra.table.TableData ;
import org.apache.jena.sparql.algebra.table.TableN;
import org.apache.jena.sparql.core.* ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.expr.Expr ;
Expand Down Expand Up @@ -98,7 +98,7 @@ public class Query extends Prologue implements Cloneable, Printable
public static final int ORDER_UNKNOW = -3 ;

// VALUES trailing clause
protected TableData valuesDataBlock = null ;
protected TableN valuesDataBlock = null ;

protected boolean strictQuery = true ;

Expand Down Expand Up @@ -601,7 +601,7 @@ public Expr allocAggregate(Aggregator agg)
public void setValuesDataBlock(List<Var> variables, List<Binding> values)
{
checkDataBlock(variables, values) ;
valuesDataBlock = new TableData(variables, values) ;
valuesDataBlock = new TableN(variables, values) ;
}

private static void checkDataBlock(List<Var> variables, List<Binding> values)
Expand Down
4 changes: 4 additions & 0 deletions jena-arq/src/main/java/org/apache/jena/query/ResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,8 @@ public default ResultSet materialise() {
}

public void close();

default RowSet toRowSet() {
return RowSet.adapt(this);
}
}
19 changes: 12 additions & 7 deletions jena-arq/src/main/java/org/apache/jena/sparql/algebra/Algebra.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,22 +161,27 @@ public static Binding merge(Binding bindingLeft, Binding bindingRight) {

// If compatible, merge. Iterate over variables in right but not in left.
BindingBuilder b = Binding.builder(bindingLeft);
for ( Iterator<Var> vIter = bindingRight.vars() ; vIter.hasNext() ; ) {
Var v = vIter.next();
Node n = bindingRight.get(v);
bindingRight.forEach((v, n) -> {
if ( !bindingLeft.contains(v) )
b.add(v, n);
}
});
return b.build();
}

public static boolean compatible(Binding bindingLeft, Binding bindingRight) {
// Test to see if compatible: Iterate over variables in left
for ( Iterator<Var> vIter = bindingLeft.vars() ; vIter.hasNext() ; ) {
Var v = vIter.next();
return compatible(bindingLeft, bindingRight, bindingLeft.vars());
}

/** Test to see if bindings are compatible for all variables of the provided iterator. */
public static boolean compatible(Binding bindingLeft, Binding bindingRight, Iterator<Var> vars) {
while (vars.hasNext() ) {
Var v = vars.next();
Node nLeft = bindingLeft.get(v);
Node nRight = bindingRight.get(v);
if ( nLeft == null )
continue;

Node nRight = bindingRight.get(v);
if ( nRight != null && !nRight.equals(nLeft) )
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,57 @@

package org.apache.jena.sparql.algebra;

import java.util.Iterator;
import java.util.List ;

import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.algebra.table.Table1 ;
import org.apache.jena.sparql.algebra.table.TableEmpty ;
import org.apache.jena.sparql.algebra.table.TableN ;
import org.apache.jena.sparql.algebra.table.TableUnit ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.binding.Binding;
import org.apache.jena.sparql.exec.RowSet;

public class TableFactory
{
public static Table createUnit()
{ return new TableUnit() ; }

public static Table createEmpty()
{ return new TableEmpty() ; }

public static Table create()
{ return new TableN() ; }

public static Table create(List<Var> vars)
{ return new TableN(vars) ; }

public static Table create(QueryIterator queryIterator)
{
{
if ( queryIterator.isJoinIdentity() ) {
queryIterator.close();
return createUnit() ;
}

return new TableN(queryIterator) ;
}

public static Table create(Var var, Node value)
{ return new Table1(var, value) ; }

/** Creates a mutable table from the detached bindings of the row set. */
public static Table create(RowSet rs)
{
List<Var> vars = rs.getResultVars();
Iterator<Binding> it = Iter.map(rs, Binding::detach);
return create(vars, it);
}

public static Table create(List<Var> vars, Iterator<Binding> bindings) {
List<Binding> list = Iter.toList(bindings);
return new TableN(vars, list);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,21 @@

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

import java.util.Collections;
import java.util.List ;

import org.apache.jena.sparql.ARQException ;
import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.binding.Binding ;

/** Immutable table. */
public class TableData extends TableN {
public TableData(List<Var> variables, List<Binding> rows) {
super(variables, rows) ;
super(Collections.unmodifiableList(variables), Collections.unmodifiableList(rows)) ;
}

@Override
public void addBinding(Binding binding) {
throw new ARQException("Can't add bindings to an existing data table") ;
}

public List<Binding> getRows() {
return rows ;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
import java.util.ArrayList ;
import java.util.Iterator ;
import java.util.List ;
import java.util.Objects;

import org.apache.jena.sparql.core.Var ;
import org.apache.jena.sparql.engine.ExecutionContext ;
import org.apache.jena.sparql.engine.QueryIterator ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper ;

/** Mutable table. */
public class TableN extends TableBase {
protected List<Binding> rows = new ArrayList<>() ;
protected List<Var> vars = new ArrayList<>() ;
Expand All @@ -48,16 +50,13 @@ public TableN(QueryIterator qIter) {
materialize(qIter) ;
}

protected TableN(List<Var> variables, List<Binding> rows) {
this.vars = variables ;
this.rows = rows ;
public TableN(List<Var> variables, List<Binding> rows) {
this.vars = Objects.requireNonNull(variables) ;
this.rows = Objects.requireNonNull(rows) ;
}

private void materialize(QueryIterator qIter) {
while (qIter.hasNext()) {
Binding binding = qIter.nextBinding() ;
addBinding(binding) ;
}
qIter.forEachRemaining(this::addBinding);
qIter.close() ;
}

Expand Down Expand Up @@ -105,4 +104,8 @@ public List<String> getVarNames() {
public List<Var> getVars() {
return vars ;
}

public List<Binding> getRows() {
return rows;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,11 @@ public default boolean contains(String varName) {

@Override
public boolean equals(Object other);

/**
* Returns a binding which is guaranteed to be independent of
* any resources such as an ongoing query execution or a disk-based dataset.
* May return itself if it is already detached.
*/
public Binding detach();
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ protected void forEach1(BiConsumer<Var, Node> action) { }

@Override
protected Node get1(Var var) { return null; }

@Override
protected Binding detachWithNewParent(Binding newParent) {
return new Binding0(newParent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,9 @@ protected Node get1(Var v) {
return value;
return null;
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
return new Binding1(newParent, var, value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,9 @@ protected Node get1(Var v)
return value2;
return null;
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
return new Binding2(newParent, var1, value1, var2, value2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,9 @@ protected Node get1(Var var) {

return null;
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
return new Binding3(newParent, var1, value1, var2, value2, var3, value3);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,9 @@ protected Node get1(Var var) {

return null;
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
return new Binding4(newParent, var1, value1, var2, value2, var3, value3, var4, value4);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,19 @@ public static int hashCode(Binding bind) {
}
return hash;
}

@Override
public Binding detach() {
Binding newParent = parent == null ? null : parent.detach();
Binding result = newParent == parent
? detachWithOriginalParent()
: detachWithNewParent(newParent);
return result;
}

protected Binding detachWithOriginalParent() {
return this;
}

protected abstract Binding detachWithNewParent(Binding newParent);
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ protected int size1() {
protected boolean isEmpty1() {
return map.isEmpty();
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
return new BindingOverMap(newParent, map);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,17 @@ public BindingProject(Collection<Var> vars, Binding bind) {
protected boolean accept(Var var) {
return projectionVars.contains(var) ;
}

@Override
public Binding detach() {
Binding b = binding.detach();
return b == binding
? this
: new BindingProject(projectionVars, b);
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
throw new UnsupportedOperationException("Should never be called.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.core.Var ;

/** Common framework for projection;
/** Common framework for projection;
* the projection policy is provided by
* abstract method {@link #accept(Var)}
* abstract method {@link #accept(Var)}
*/
public abstract class BindingProjectBase extends BindingBase {
private List<Var> actualVars = null ;
private final Binding binding ;
protected final Binding binding ;

public BindingProjectBase(Binding bind) {
super(null) ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,17 @@ public BindingProjectNamed(Binding bind) {
protected boolean accept(Var var) {
return var.isNamedVar() ;
}

@Override
public Binding detach() {
Binding b = binding.detach();
return b == binding
? this
: new BindingProjectNamed(b);
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
throw new UnsupportedOperationException("Should never be called.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,9 @@ private BindingRoot() {
public void format1(StringBuilder sBuff) {
sBuff.append("[Root]");
}

@Override
protected Binding detachWithNewParent(Binding newParent) {
return this;
}
}
Loading

0 comments on commit 645968d

Please sign in to comment.