@Override
protected Iterator<BindingNodeId> makeNextStage(final BindingNodeId input)
{
// ---- Convert to NodeIds
NodeId ids[] = new NodeId[patternTuple.size()] ;
// Variables for this tuple after subsitution
final Var[] var = new Var[patternTuple.size()] ;
prepare(nodeTupleTable.getNodeTable(), patternTuple, input, ids, var) ;
Iterator<Tuple<NodeId>> iterMatches = nodeTupleTable.find(Tuple.create(ids)) ;
// ** Allow a triple or quad filter here.
if ( filter != null )
iterMatches = Iter.filter(iterMatches, filter) ;
// If we want to reduce to RDF semantics over quads,
// we need to reduce the quads to unique triples.
// We do that by having the graph slot as "any", then running
// through a distinct-ifier.
// Assumes quads are GSPO - zaps the first slot.
// Assumes that tuples are not shared.
if ( anyGraphs )
{
iterMatches = Iter.operate(iterMatches, quadsToAnyTriples) ;
// If any slots were set, then the index would be ???G and we can use distinctAdjacent.
// If all slots are unset, the index is probably GSPO (SPOG would be better in this one case).
// This is a safe, if potentially costly, choice.
//Guaranteed
//iterMatches = Iter.distinct(iterMatches) ;
// This depends on the way indexes are choose and
// the indexing pattern. It assumes that the index
// chosen ends in G so same triples are adjacent
// in a union query.
// If any slot is defined, then the index will be X??G.
// if no slot is defined, then the index will be ???G.
// See TupleTable.scanAllIndex that ensures the latter.
// The former assumes indexes are either G... or ...G.
// No G part way through.
iterMatches = Iter.distinctAdjacent(iterMatches) ;
}
// Map Tuple<NodeId> to BindingNodeId
Transform<Tuple<NodeId>, BindingNodeId> binder = new Transform<Tuple<NodeId>, BindingNodeId>()
{
@Override
public BindingNodeId convert(Tuple<NodeId> tuple)
{
BindingNodeId output = new BindingNodeId(input) ;
for ( int i = 0 ; i < var.length ; i++ )
{
Var v = var[i] ;
if ( v == null )
continue ;
NodeId id = tuple.get(i) ;
if ( reject(output, v, id) )
return null ;
output.put(v, id) ;
}
return output ;