Skip to content

Commit 151c313

Browse files
authored
Merge main into develop (#4877)
2 parents 0ef1d99 + 4884913 commit 151c313

33 files changed

Lines changed: 996 additions & 311 deletions

File tree

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/ArrayBindingSet.java

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Iterator;
1717
import java.util.LinkedHashSet;
1818
import java.util.List;
19+
import java.util.NoSuchElementException;
1920
import java.util.Set;
2021
import java.util.function.BiConsumer;
2122
import java.util.function.Function;
@@ -80,6 +81,7 @@ public ArrayBindingSet(BindingSet toCopy, Set<String> names, String[] namesArray
8081
}
8182
}
8283
this.empty = toCopy.isEmpty();
84+
assert !this.empty || size() == 0;
8385

8486
}
8587

@@ -90,6 +92,7 @@ public ArrayBindingSet(ArrayBindingSet toCopy, String... names) {
9092
this.whichBindingsHaveBeenSet = Arrays.copyOf(toCopy.whichBindingsHaveBeenSet,
9193
toCopy.whichBindingsHaveBeenSet.length);
9294
this.empty = toCopy.empty;
95+
assert !this.empty || size() == 0;
9396
}
9497

9598
/**
@@ -182,6 +185,10 @@ private int getIndex(String bindingName) {
182185

183186
@Override
184187
public Set<String> getBindingNames() {
188+
if (isEmpty()) {
189+
return Collections.emptySet();
190+
}
191+
185192
if (bindingNamesSetCache == null) {
186193
int size = size();
187194
if (size == 0) {
@@ -210,6 +217,10 @@ public Set<String> getBindingNames() {
210217

211218
@Override
212219
public Value getValue(String bindingName) {
220+
if (isEmpty()) {
221+
return null;
222+
}
223+
213224
for (int i = 0; i < bindingNames.length; i++) {
214225
if (bindingNames[i] == bindingName && whichBindingsHaveBeenSet[i]) {
215226
return values[i];
@@ -226,6 +237,10 @@ public Value getValue(String bindingName) {
226237

227238
@Override
228239
public Binding getBinding(String bindingName) {
240+
if (isEmpty()) {
241+
return null;
242+
}
243+
229244
Value value = getValue(bindingName);
230245

231246
if (value != null) {
@@ -237,6 +252,10 @@ public Binding getBinding(String bindingName) {
237252

238253
@Override
239254
public boolean hasBinding(String bindingName) {
255+
if (isEmpty()) {
256+
return false;
257+
}
258+
240259
int index = getIndex(bindingName);
241260
if (index == -1) {
242261
return false;
@@ -246,14 +265,19 @@ public boolean hasBinding(String bindingName) {
246265

247266
@Override
248267
public Iterator<Binding> iterator() {
268+
if (isEmpty()) {
269+
return Collections.emptyIterator();
270+
}
271+
249272
return new ArrayBindingSetIterator();
250273
}
251274

252275
@Override
253276
public int size() {
254-
if (empty) {
277+
if (isEmpty()) {
255278
return 0;
256279
}
280+
257281
int size = 0;
258282

259283
for (boolean value : whichBindingsHaveBeenSet) {
@@ -268,6 +292,7 @@ public int size() {
268292
List<String> sortedBindingNames = null;
269293

270294
public List<String> getSortedBindingNames() {
295+
271296
if (sortedBindingNames == null) {
272297
int size = size();
273298

@@ -292,50 +317,6 @@ public List<String> getSortedBindingNames() {
292317
return sortedBindingNames;
293318
}
294319

295-
/*------------------------------------*
296-
* Inner class ArrayBindingSetIterator *
297-
*------------------------------------*/
298-
299-
private class ArrayBindingSetIterator implements Iterator<Binding> {
300-
301-
private int index = 0;
302-
303-
public ArrayBindingSetIterator() {
304-
}
305-
306-
@Override
307-
public boolean hasNext() {
308-
for (; index < values.length; index++) {
309-
if (whichBindingsHaveBeenSet[index] && values[index] != null) {
310-
return true;
311-
}
312-
}
313-
return false;
314-
}
315-
316-
@Override
317-
public Binding next() {
318-
for (; index < values.length; index++) {
319-
if (whichBindingsHaveBeenSet[index] && values[index] != null) {
320-
break;
321-
}
322-
}
323-
324-
String name = bindingNames[index];
325-
Value value = values[index++];
326-
if (value != null) {
327-
return new SimpleBinding(name, value);
328-
} else {
329-
return null;
330-
}
331-
}
332-
333-
@Override
334-
public void remove() {
335-
throw new UnsupportedOperationException();
336-
}
337-
}
338-
339320
@Override
340321
public void addBinding(Binding binding) {
341322
int index = getIndex(binding.getName());
@@ -350,8 +331,8 @@ public void addBinding(Binding binding) {
350331
assert !this.whichBindingsHaveBeenSet[index];
351332
this.values[index] = binding.getValue();
352333
this.whichBindingsHaveBeenSet[index] = true;
334+
empty = false;
353335
clearCache();
354-
355336
}
356337

357338
@Override
@@ -362,6 +343,7 @@ public void setBinding(Binding binding) {
362343
}
363344
this.values[index] = binding.getValue();
364345
this.whichBindingsHaveBeenSet[index] = true;
346+
empty = false;
365347
clearCache();
366348
}
367349

@@ -382,6 +364,8 @@ public void setBinding(String name, Value value) {
382364
break;
383365
}
384366
}
367+
} else {
368+
this.empty = false;
385369
}
386370
clearCache();
387371
}
@@ -418,4 +402,46 @@ public void addAll(ArrayBindingSet other) {
418402

419403
}
420404

405+
private class ArrayBindingSetIterator implements Iterator<Binding> {
406+
407+
private int index = 0;
408+
409+
public ArrayBindingSetIterator() {
410+
}
411+
412+
@Override
413+
public boolean hasNext() {
414+
while (index < values.length) {
415+
if (whichBindingsHaveBeenSet[index]) {
416+
return true;
417+
}
418+
index++;
419+
}
420+
return false;
421+
}
422+
423+
@Override
424+
public Binding next() {
425+
while (index < values.length) {
426+
if (whichBindingsHaveBeenSet[index]) {
427+
String name = bindingNames[index];
428+
Value value = values[index++];
429+
if (value != null) {
430+
return new SimpleBinding(name, value);
431+
} else {
432+
return null;
433+
}
434+
}
435+
index++;
436+
}
437+
438+
throw new NoSuchElementException();
439+
}
440+
441+
@Override
442+
public void remove() {
443+
throw new UnsupportedOperationException();
444+
}
445+
}
446+
421447
}

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/ArrayBindingBasedQueryEvaluationContext.java

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public final class ArrayBindingBasedQueryEvaluationContext implements QueryEvalu
5757
private final BiConsumer<Value, MutableBindingSet>[] addBinding;
5858
private final Comparator<Value> comparator;
5959

60-
boolean initialized;
60+
private final boolean initialized;
6161

6262
ArrayBindingBasedQueryEvaluationContext(QueryEvaluationContext context, String[] allVariables,
6363
Comparator<Value> comparator) {
@@ -118,7 +118,12 @@ public Predicate<BindingSet> hasBinding(String variableName) {
118118

119119
assert variableName != null && !variableName.isEmpty();
120120
Function<ArrayBindingSet, Boolean> directHasVariable = defaultArrayBindingSet.getDirectHasBinding(variableName);
121-
return new HasBinding(variableName, directHasVariable);
121+
if (directHasVariable != null) {
122+
return new HasBinding(variableName, directHasVariable);
123+
} else {
124+
// If the variable is not in the default set, it can never be part of this array binding
125+
return (bs) -> false;
126+
}
122127
}
123128

124129
static private class HasBinding implements Predicate<BindingSet> {
@@ -156,16 +161,19 @@ public Function<BindingSet, Binding> getBinding(String variableName) {
156161

157162
Function<ArrayBindingSet, Binding> directAccessForVariable = defaultArrayBindingSet
158163
.getDirectGetBinding(variableName);
159-
return bs -> {
160-
if (bs.isEmpty()) {
161-
return null;
162-
}
163-
if (bs instanceof ArrayBindingSet) {
164-
return directAccessForVariable.apply((ArrayBindingSet) bs);
165-
} else {
166-
return bs.getBinding(variableName);
167-
}
168-
};
164+
if (directAccessForVariable != null) {
165+
return (bs) -> {
166+
if (bs.isEmpty()) {
167+
return null;
168+
} else if (bs instanceof ArrayBindingSet) {
169+
return directAccessForVariable.apply((ArrayBindingSet) bs);
170+
} else {
171+
return bs.getBinding(variableName);
172+
}
173+
};
174+
} else {
175+
return (bs) -> null;
176+
}
169177
}
170178

171179
@Override
@@ -180,7 +188,12 @@ public Function<BindingSet, Value> getValue(String variableName) {
180188

181189
Function<ArrayBindingSet, Value> directAccessForVariable = defaultArrayBindingSet
182190
.getDirectGetValue(variableName);
183-
return new ValueGetter(variableName, directAccessForVariable);
191+
if (directAccessForVariable != null) {
192+
return new ValueGetter(variableName, directAccessForVariable);
193+
} else {
194+
// If the variable is not in the default set, it can never be part of this array binding
195+
return (bs) -> null;
196+
}
184197
}
185198

186199
private static class ValueGetter implements Function<BindingSet, Value> {
@@ -219,13 +232,17 @@ public BiConsumer<Value, MutableBindingSet> setBinding(String variableName) {
219232

220233
BiConsumer<Value, ArrayBindingSet> directAccessForVariable = defaultArrayBindingSet
221234
.getDirectSetBinding(variableName);
222-
return (val, bs) -> {
223-
if (bs instanceof ArrayBindingSet) {
224-
directAccessForVariable.accept(val, (ArrayBindingSet) bs);
225-
} else {
226-
bs.setBinding(variableName, val);
227-
}
228-
};
235+
if (directAccessForVariable != null) {
236+
return (val, bs) -> {
237+
if (bs instanceof ArrayBindingSet) {
238+
directAccessForVariable.accept(val, (ArrayBindingSet) bs);
239+
} else {
240+
bs.setBinding(variableName, val);
241+
}
242+
};
243+
} else {
244+
return (val, bs) -> bs.setBinding(variableName, val);
245+
}
229246
}
230247

231248
@Override
@@ -240,13 +257,17 @@ public BiConsumer<Value, MutableBindingSet> addBinding(String variableName) {
240257

241258
BiConsumer<Value, ArrayBindingSet> wrapped = defaultArrayBindingSet
242259
.getDirectAddBinding(variableName);
243-
return (val, bs) -> {
244-
if (bs instanceof ArrayBindingSet) {
245-
wrapped.accept(val, (ArrayBindingSet) bs);
246-
} else {
247-
bs.addBinding(variableName, val);
248-
}
249-
};
260+
if (wrapped != null) {
261+
return (val, bs) -> {
262+
if (bs instanceof ArrayBindingSet) {
263+
wrapped.accept(val, (ArrayBindingSet) bs);
264+
} else {
265+
bs.addBinding(variableName, val);
266+
}
267+
};
268+
} else {
269+
return (val, bs) -> bs.addBinding(variableName, val);
270+
}
250271
}
251272

252273
@Override

core/queryalgebra/evaluation/src/main/java/org/eclipse/rdf4j/query/algebra/evaluation/impl/DefaultEvaluationStrategy.java

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.util.concurrent.TimeUnit;
1818
import java.util.function.BiFunction;
1919
import java.util.function.Consumer;
20+
import java.util.function.Predicate;
2021
import java.util.function.Supplier;
2122

2223
import org.eclipse.rdf4j.collection.factory.api.CollectionFactory;
@@ -616,29 +617,8 @@ protected QueryEvaluationStep prepare(Service service, QueryEvaluationContext co
616617

617618
protected QueryEvaluationStep prepare(Filter node, QueryEvaluationContext context) throws QueryEvaluationException {
618619

619-
QueryEvaluationStep arg = precompile(node.getArg(), context);
620-
QueryValueEvaluationStep ves;
621-
try {
622-
ves = precompile(node.getCondition(), context);
623-
} catch (QueryEvaluationException e) {
624-
// If we have a failed compilation we always return false.
625-
// Which means empty. so let's short circuit that.
626-
// ves = new QueryValueEvaluationStep.ConstantQueryValueEvaluationStep(BooleanLiteral.FALSE);
627-
return bs -> QueryEvaluationStep.EMPTY_ITERATION;
628-
}
629-
return bs -> {
630-
CloseableIteration<BindingSet> evaluate = null;
631-
try {
632-
evaluate = arg.evaluate(bs);
633-
return new FilterIterator(evaluate, ves, DefaultEvaluationStrategy.this);
634-
} catch (Throwable t) {
635-
if (evaluate != null) {
636-
evaluate.close();
637-
}
638-
throw t;
639-
}
620+
return FilterIterator.supply(node, DefaultEvaluationStrategy.this, context);
640621

641-
};
642622
}
643623

644624
protected QueryEvaluationStep prepare(Order node, QueryEvaluationContext context) throws QueryEvaluationException {
@@ -939,12 +919,13 @@ protected QueryValueEvaluationStep prepare(Var var, QueryEvaluationContext conte
939919
return new ConstantQueryValueEvaluationStep(value);
940920
} else {
941921
java.util.function.Function<BindingSet, Value> getValue = context.getValue(var.getName());
922+
Predicate<BindingSet> hasValue = context.hasBinding(var.getName());
942923
return bindings -> {
943-
Value value1 = getValue.apply(bindings);
944-
if (value1 == null) {
924+
if (hasValue.test(bindings)) {
925+
return getValue.apply(bindings);
926+
} else {
945927
throw new ValueExprEvaluationException();
946928
}
947-
return value1;
948929
};
949930
}
950931

0 commit comments

Comments
 (0)