1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/*
* SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/>
*
* SPDX-License-Identifier: EPL-2.0
*/
package tools.refinery.store.query.interpreter;
import org.junit.jupiter.api.Test;
import tools.refinery.store.model.ModelStore;
import tools.refinery.store.query.ModelQueryAdapter;
import tools.refinery.store.query.dnf.Query;
import tools.refinery.store.query.term.int_.IntTerms;
import tools.refinery.store.query.view.AnySymbolView;
import tools.refinery.store.query.view.FunctionView;
import tools.refinery.store.query.view.KeyOnlyView;
import tools.refinery.store.representation.Symbol;
import tools.refinery.store.tuple.Tuple;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertNullableResults;
import static tools.refinery.store.query.interpreter.tests.QueryAssertions.assertResults;
class LeftJoinTest {
private static final Symbol<Boolean> person = Symbol.of("Person", 1);
private static final Symbol<Integer> age = Symbol.of("age", 1, Integer.class);
private static final AnySymbolView personView = new KeyOnlyView<>(person);
private static final FunctionView<Integer> ageView = new FunctionView<>(age);
@Test
void unarySymbolTest() {
var query = Query.of("Query", Integer.class, (builder, p1, output) -> builder
.clause(
personView.call(p1),
output.assign(ageView.leftJoin(18, p1))
));
var store = ModelStore.builder()
.symbols(person, age)
.with(QueryInterpreterAdapter.builder()
.queries(query))
.build();
var model = store.createEmptyModel();
var personInterpretation = model.getInterpretation(person);
var ageInterpretation = model.getInterpretation(age);
var queryEngine = model.getAdapter(ModelQueryAdapter.class);
var queryResultSet = queryEngine.getResultSet(query);
personInterpretation.put(Tuple.of(0), true);
personInterpretation.put(Tuple.of(1), true);
personInterpretation.put(Tuple.of(2), true);
ageInterpretation.put(Tuple.of(2), 24);
queryEngine.flushChanges();
assertNullableResults(Map.of(
Tuple.of(0), Optional.of(18),
Tuple.of(1), Optional.of(18),
Tuple.of(2), Optional.of(24),
Tuple.of(3), Optional.empty()
), queryResultSet);
personInterpretation.put(Tuple.of(0), false);
ageInterpretation.put(Tuple.of(1), 20);
ageInterpretation.put(Tuple.of(2), null);
queryEngine.flushChanges();
assertNullableResults(Map.of(
Tuple.of(0), Optional.empty(),
Tuple.of(1), Optional.of(20),
Tuple.of(2), Optional.of(18),
Tuple.of(3), Optional.empty()
), queryResultSet);
}
@Test
void unarySymbolWithAssignmentTest() {
// Tests an edge case where the outer joined variable is already bound in the query plan.
var query = Query.of("Query", (builder, p1) -> builder
.clause(Integer.class, v1 -> List.of(
personView.call(p1),
v1.assign(IntTerms.constant(18)),
v1.assign(ageView.leftJoin(18, p1))
)));
var store = ModelStore.builder()
.symbols(person, age)
.with(QueryInterpreterAdapter.builder()
.queries(query))
.build();
var model = store.createEmptyModel();
var personInterpretation = model.getInterpretation(person);
var ageInterpretation = model.getInterpretation(age);
var queryEngine = model.getAdapter(ModelQueryAdapter.class);
var queryResultSet = queryEngine.getResultSet(query);
personInterpretation.put(Tuple.of(0), true);
personInterpretation.put(Tuple.of(1), true);
personInterpretation.put(Tuple.of(2), true);
ageInterpretation.put(Tuple.of(2), 24);
queryEngine.flushChanges();
assertResults(Map.of(
Tuple.of(0), true,
Tuple.of(1), true,
Tuple.of(2), false,
Tuple.of(3), false
), queryResultSet);
personInterpretation.put(Tuple.of(0), false);
ageInterpretation.put(Tuple.of(1), 20);
ageInterpretation.put(Tuple.of(2), null);
queryEngine.flushChanges();
assertResults(Map.of(
Tuple.of(0), false,
Tuple.of(1), false,
Tuple.of(2), true,
Tuple.of(3), false
), queryResultSet);
}
}
|