1010 *******************************************************************************/
1111package org .eclipse .rdf4j .query .algebra .evaluation .iterator ;
1212
13+ import java .util .HashSet ;
1314import java .util .Queue ;
1415import java .util .Set ;
1516
@@ -66,6 +67,8 @@ public class PathIteration extends LookAheadIteration<BindingSet, QueryEvaluatio
6667
6768 private static final String JOINVAR_PREFIX = "intermediate_join_" ;
6869
70+ private final Set <String > namedIntermediateJoins = new HashSet <>();
71+
6972 public PathIteration (EvaluationStrategy strategy , Scope scope , Var startVar ,
7073 TupleExpr pathExpression , Var endVar , Var contextVar , long minLength , BindingSet bindings )
7174 throws QueryEvaluationException {
@@ -104,10 +107,10 @@ protected BindingSet getNextElement() throws QueryEvaluationException {
104107
105108 while (currentIter != null && currentIter .hasNext ()) {
106109 BindingSet potentialNextElement = currentIter .next ();
107- MutableBindingSet nextElement ;
110+ QueryBindingSet nextElement ;
108111 // if it is not a compatible type of BindingSet
109112 if (potentialNextElement instanceof QueryBindingSet ) {
110- nextElement = (MutableBindingSet ) potentialNextElement ;
113+ nextElement = (QueryBindingSet ) potentialNextElement ;
111114 } else {
112115 nextElement = new QueryBindingSet (potentialNextElement );
113116 }
@@ -121,22 +124,10 @@ protected BindingSet getNextElement() throws QueryEvaluationException {
121124 }
122125 }
123126
124- Value v1 , v2 ;
125-
126- if (startVarFixed && endVarFixed && currentLength > 2 ) {
127- v1 = getVarValue (startVar , startVarFixed , nextElement );
128- v2 = nextElement .getValue ("END_" + JOINVAR_PREFIX + this .hashCode ());
129- } else if (startVarFixed && endVarFixed && currentLength == 2 ) {
130- v1 = getVarValue (startVar , startVarFixed , nextElement );
131- v2 = nextElement .getValue (JOINVAR_PREFIX + (currentLength - 1 ) + "_" + this .hashCode ());
132- } else {
133- v1 = getVarValue (startVar , startVarFixed , nextElement );
134- v2 = getVarValue (endVar , endVarFixed , nextElement );
135- }
127+ ValuePair vp = valuePairFromStartAndEnd (nextElement );
136128
137- if (!isCyclicPath (v1 , v2 )) {
129+ if (!isCyclicPath (vp )) {
138130
139- ValuePair vp = new ValuePair (v1 , v2 );
140131 if (reportedValues .contains (vp )) {
141132 // new arbitrary-length path semantics: filter out
142133 // duplicates
@@ -151,38 +142,38 @@ protected BindingSet getNextElement() throws QueryEvaluationException {
151142
152143 if (startVarFixed && endVarFixed ) {
153144 Value endValue = getVarValue (endVar , endVarFixed , nextElement );
154- if (endValue .equals (v2 )) {
145+ if (endValue .equals (vp . endValue )) {
155146 add (reportedValues , vp );
156- if (!v1 . equals (v2 )) {
147+ if (!vp . startValue . equals (vp . endValue )) {
157148 addToQueue (valueQueue , vp );
158149 }
159150 if (!nextElement .hasBinding (startVar .getName ())) {
160- addBinding (nextElement , startVar .getName (), v1 );
151+ addBinding (nextElement , startVar .getName (), vp . startValue );
161152 }
162153 if (!nextElement .hasBinding (endVar .getName ())) {
163- addBinding (nextElement , endVar .getName (), v2 );
154+ addBinding (nextElement , endVar .getName (), vp . endValue );
164155 }
165- return nextElement ;
156+ return removeIntermediateJoinVars ( nextElement ) ;
166157 } else {
167158 if (add (unreportedValues , vp )) {
168- if (!v1 . equals (v2 )) {
159+ if (!vp . startValue . equals (vp . endValue )) {
169160 addToQueue (valueQueue , vp );
170161 }
171162 }
172163 continue again ;
173164 }
174165 } else {
175166 add (reportedValues , vp );
176- if (!v1 . equals (v2 )) {
167+ if (!vp . startValue . equals (vp . endValue )) {
177168 addToQueue (valueQueue , vp );
178169 }
179170 if (!nextElement .hasBinding (startVar .getName ())) {
180- addBinding (nextElement , startVar .getName (), v1 );
171+ addBinding (nextElement , startVar .getName (), vp . startValue );
181172 }
182173 if (!nextElement .hasBinding (endVar .getName ())) {
183- addBinding (nextElement , endVar .getName (), v2 );
174+ addBinding (nextElement , endVar .getName (), vp . endValue );
184175 }
185- return nextElement ;
176+ return removeIntermediateJoinVars ( nextElement ) ;
186177 }
187178 } else {
188179 continue again ;
@@ -198,6 +189,27 @@ protected BindingSet getNextElement() throws QueryEvaluationException {
198189 }
199190 }
200191
192+ private BindingSet removeIntermediateJoinVars (QueryBindingSet nextElement ) {
193+ nextElement .removeAll (namedIntermediateJoins );
194+ return nextElement ;
195+ }
196+
197+ private ValuePair valuePairFromStartAndEnd (MutableBindingSet nextElement ) {
198+ Value v1 , v2 ;
199+
200+ if (startVarFixed && endVarFixed && currentLength > 2 ) {
201+ v1 = getVarValue (startVar , startVarFixed , nextElement );
202+ v2 = nextElement .getValue ("END_" + JOINVAR_PREFIX + this .hashCode ());
203+ } else if (startVarFixed && endVarFixed && currentLength == 2 ) {
204+ v1 = getVarValue (startVar , startVarFixed , nextElement );
205+ v2 = nextElement .getValue (JOINVAR_PREFIX + (currentLength - 1 ) + "_" + this .hashCode ());
206+ } else {
207+ v1 = getVarValue (startVar , startVarFixed , nextElement );
208+ v2 = getVarValue (endVar , endVarFixed , nextElement );
209+ }
210+ return new ValuePair (v1 , v2 );
211+ }
212+
201213 private void addBinding (MutableBindingSet bs , String name , Value value ) {
202214 bs .addBinding (name , value );
203215 }
@@ -242,12 +254,12 @@ private Value getVarValue(Var var, boolean fixedValue, BindingSet bindingSet) {
242254 return v ;
243255 }
244256
245- private boolean isCyclicPath (Value v1 , Value v2 ) {
257+ private boolean isCyclicPath (ValuePair vp ) {
246258 if (currentLength <= 2 ) {
247259 return false ;
248260 }
249261
250- return reportedValues .contains (new ValuePair ( v1 , v2 ) );
262+ return reportedValues .contains (vp );
251263
252264 }
253265
@@ -426,9 +438,12 @@ public void meet(Var var) {
426438
427439 }
428440
441+ private Var createAnonVar (String varName , Value v , boolean anonymous ) {
442+ namedIntermediateJoins .add (varName );
443+ return new Var (varName , null , anonymous , false );
444+ }
445+
429446 public Var createAnonVar (String varName ) {
430- Var var = new Var (varName );
431- var .setAnonymous (true );
432- return var ;
447+ return createAnonVar (varName , null , true );
433448 }
434449}
0 commit comments