public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(ZeroLengthPath zlp, final BindingSet bindings) throws QueryEvaluationException { final Var subjectVar = zlp.getSubjectVar(); final Var objVar = zlp.getObjectVar(); final Var contextVar = zlp.getContextVar(); Value subj = null; try { subj = evaluate(subjectVar, bindings); } catch (QueryEvaluationException e) { } Value obj = null; try { obj = evaluate(objVar, bindings); } catch (QueryEvaluationException e) { } if (subj != null && obj != null) { if (!subj.equals(obj)) { return new EmptyIteration<BindingSet, QueryEvaluationException>(); } } return getZeroLengthPathIterator(bindings, subjectVar, objVar, contextVar, subj, obj); }
@Override public boolean equals(Object other) { if (other instanceof ZeroLengthPath) { ZeroLengthPath o = (ZeroLengthPath)other; return subjectVar.equals(o.getSubjectVar()) && objectVar.equals(o.getObjectVar()) && nullEquals(contextVar, o.getContextVar()) && scope.equals(o.getScope()); } return false; }
@Override public void meet(ZeroLengthPath node) { Var subjVar = node.getSubjectVar(); Var objVar = node.getObjectVar(); if((subjVar != null && subjVar.hasValue()) || (objVar != null && objVar.hasValue())) { // subj = obj cardinality = 1.0; } else { // actual cardinality = count(union(subjs, objs)) // but cost is equivalent to ?s ?p ?o ?c (impl scans all statements) // so due to the lower actual cardinality we value it in preference to a fully unbound statement pattern. cardinality = getSubjectCardinality(subjVar) * getObjectCardinality(objVar) * getContextCardinality(node.getContextVar()); } }
@Override public ZeroLengthPath clone() { ZeroLengthPath clone = (ZeroLengthPath)super.clone(); clone.setSubjectVar(getSubjectVar().clone()); clone.setObjectVar(getObjectVar().clone()); if (getContextVar() != null) { clone.setContextVar(getContextVar().clone()); } return clone; } }
@Override public void meet(final Union n) { final TupleExpr l = n.getLeftArg(); final TupleExpr r = n.getRightArg(); final ZeroLengthPath p = l instanceof ZeroLengthPath ? (ZeroLengthPath) l : r instanceof ZeroLengthPath ? (ZeroLengthPath) r : null; if (p == null) { emit(l, !(l instanceof Union)).emit(" UNION ").emit(r, !(r instanceof Union)); } else { final Var s = p.getSubjectVar(); final Var o = p.getObjectVar(); final Var c = p.getContextVar(); if (c != null) { emit("GRAPH ").emit(c).emit(" ").openBrace(); } emit(s).emit(" ").emitPropertyPath(n, s, o).emit(" ").emit(o); if (c != null) { closeBrace(); } } }
@Override public void meet(final Union n) { final TupleExpr l = n.getLeftArg(); final TupleExpr r = n.getRightArg(); final ZeroLengthPath p = l instanceof ZeroLengthPath ? (ZeroLengthPath) l : r instanceof ZeroLengthPath ? (ZeroLengthPath) r : null; if (p == null) { emit(l, !(l instanceof Union)).emit(" UNION ").emit(r, !(r instanceof Union)); } else { final Var s = p.getSubjectVar(); final Var o = p.getObjectVar(); final Var c = p.getContextVar(); if (c != null) { emit("GRAPH ").emit(c).emit(" ").openBrace(); } emit(s).emit(" ").emitPropertyPath(n, s, o).emit(" ").emit(o); if (c != null) { closeBrace(); } } }