Skip to content

Commit 29a68e7

Browse files
Add variable binding behaviour tests (#413)
## Usage and product changes Tests variable binding behaviour cases ranging disjunctions
1 parent fa48560 commit 29a68e7

3 files changed

Lines changed: 311 additions & 2 deletions

File tree

query/language/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ files = [
2121
"reduce.feature",
2222
"undefine.feature",
2323
"update.feature",
24+
"variables.feature",
2425
]
2526

2627
filegroup(

query/language/optional.feature

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ Feature: TypeQL Optional
154154

155155

156156
Scenario: an optional cannot be used within a disjunction
157-
When typeql read query; fails with a message containing: "cannot be re-used elsewhere as a locally-scoped variable"
157+
# TODO: Better error messages from core again
158+
# Then typeql read query; fails with a message containing: "cannot be re-used elsewhere as a locally-scoped variable"
159+
Then typeql read query; fails with a message containing: "is required to be bound to a value before it's used"
158160
"""
159161
match $x isa person, has name "Frank";
160162
{
@@ -194,7 +196,10 @@ Feature: TypeQL Optional
194196
Then uniquely identify answer concepts
195197
| x | r1 | r2 |
196198
| key:ref:1 | key:ref:3 | key:ref:3 |
197-
Then typeql read query; fails with a message containing: "cannot be re-used elsewhere as a locally-scoped variable"
199+
# TODO: Better error messages from core again
200+
# Then typeql read query; fails with a message containing: "cannot be re-used elsewhere as a locally-scoped variable"
201+
Then typeql read query; fails with a message containing: "The variable 'y' is required to be bound to a value before it's used"
202+
198203
"""
199204
match
200205
$x isa person, has name "Eve";

query/language/variables.feature

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this
3+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
#noinspection CucumberUndefinedStep
6+
Feature: TypeQL Define Query
7+
# Note: Most rules across stages are repeated in pipeline.feature
8+
Background: Open connection and create a simple extensible schema
9+
Given typedb starts
10+
Given connection opens with default authentication
11+
Given connection is open: true
12+
Given connection reset database: typedb
13+
Given connection open schema transaction for database: typedb
14+
15+
Given typeql schema query
16+
"""
17+
define
18+
entity person, owns ref @key, owns name @card(0..);
19+
attribute name, value string;
20+
attribute ref, value integer;
21+
attribute number @independent, value integer;
22+
"""
23+
Given transaction commits
24+
25+
#
26+
# Given connection open write transaction for database: typedb
27+
# When typeql write query
28+
# """
29+
# insert
30+
# $_ isa number 1;
31+
# $_ isa number 11;
32+
# """
33+
# Then transaction commits
34+
35+
Scenario: Variables are available in the next stage
36+
Given connection open read transaction for database: typedb
37+
When get answers of typeql read query
38+
"""
39+
match let $x = 1;
40+
match let $y = $x + 2;
41+
"""
42+
Then uniquely identify answer concepts
43+
| y |
44+
| value:integer:3 |
45+
46+
47+
Scenario: Variables are not available in subsequent stages if they are not selected by a select stage
48+
Given connection open read transaction for database: typedb
49+
Then typeql read query; fails with a message containing: "Invalid query containing unbound concept variable x"
50+
"""
51+
match
52+
let $x = 1;
53+
let $a = 2;
54+
select $a;
55+
match
56+
let $y = $x + 2;
57+
"""
58+
59+
60+
Scenario: Variables are not available in subsequent stages if they are aggregated over by a reduce stage
61+
Given connection open read transaction for database: typedb
62+
Then typeql read query; fails with a message containing: "Invalid query containing unbound concept variable x"
63+
"""
64+
match
65+
let $x = 1;
66+
reduce $c = sum($x);
67+
match
68+
let $y = $x + 2;
69+
"""
70+
71+
72+
Scenario: Variables which occur in all branches of a disjunction are available in the root & subsequent stages
73+
Given connection open read transaction for database: typedb
74+
When get answers of typeql read query
75+
"""
76+
match
77+
{ let $x = 1; } or { let $x = 11; };
78+
let $y = $x + 2;
79+
"""
80+
Then uniquely identify answer concepts
81+
| y |
82+
| value:integer:3 |
83+
| value:integer:13 |
84+
85+
When get answers of typeql read query
86+
"""
87+
match
88+
{ let $x = 1; } or { let $x = 11; };
89+
match
90+
let $y = $x + 2;
91+
"""
92+
Then uniquely identify answer concepts
93+
| y |
94+
| value:integer:3 |
95+
| value:integer:13 |
96+
97+
When get answers of typeql read query
98+
"""
99+
# Skip a level
100+
match
101+
{
102+
{ let $x = 1; } or { let $x = 11; };
103+
} or {
104+
{ let $x = 6; } or { let $x = 16; };
105+
};
106+
match
107+
let $y = $x + 2;
108+
"""
109+
Then uniquely identify answer concepts
110+
| y |
111+
| value:integer:3 |
112+
| value:integer:13 |
113+
| value:integer:8 |
114+
| value:integer:18 |
115+
116+
117+
Scenario: Variables which occur in only some branches of a disjunction and are NOT BOUND in a parent conjunction are not available in the root & subsequent stages
118+
Given connection open read transaction for database: typedb
119+
Then typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
120+
"""
121+
match
122+
{ let $x = 1; let $a = 100; } or { let $z = 11; let $a = 100; };
123+
let $y = $x + 2;
124+
"""
125+
126+
Then typeql read query; fails with a message containing: "Invalid query containing unbound concept variable x"
127+
"""
128+
match
129+
{ let $x = 1; let $a = 100; } or { let $z = 11; let $a = 100; };
130+
match
131+
let $y = $x + 2;
132+
"""
133+
134+
135+
Scenario: Variables which occur in only some branches of a disjunction and ARE BOUND in a parent conjunction are available in subsequent stages
136+
Given connection open read transaction for database: typedb
137+
When get answers of typeql read query
138+
"""
139+
match
140+
let $x = 1; let $a = 10;
141+
{ $x < 5; $a > 5; } or { $a < 15; };
142+
match
143+
let $y = $x + 2;
144+
"""
145+
Then uniquely identify answer concepts
146+
| y |
147+
| value:integer:3 |
148+
149+
When get answers of typeql read query
150+
"""
151+
match
152+
let $a = 10;
153+
{ let $x = 1; } or { let $x = 11; };
154+
{ $x < 5; $a > 5; } or { $a < 15; };
155+
match
156+
let $y = $x + 2;
157+
"""
158+
Then uniquely identify answer concepts
159+
| y |
160+
| value:integer:3 |
161+
| value:integer:13 |
162+
163+
164+
165+
Scenario: Variables which occur in only some branches of two separate disjunctions MUST BE BOUND in a common ancestor conjunction
166+
Given connection open read transaction for database: typedb
167+
When get answers of typeql read query
168+
"""
169+
match
170+
let $x = 1; let $a = 10;
171+
{ $x < 5; $a > 5; } or { $a < 15; };
172+
{ $a < 20; } or { $x > 0; $a > 0; };
173+
match
174+
let $y = $x + 2;
175+
"""
176+
Then uniquely identify answer concepts
177+
| y |
178+
| value:integer:3 |
179+
180+
# TODO: Might be better with disjoint variable error "Locally-scoped variable 'x' cannot be re-used elsewhere as a locally-scoped variable"
181+
Then typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
182+
"""
183+
match
184+
let $a = 10;
185+
{ let $x = 1; $x < 5; $a > 5; } or { $a < 15; };
186+
{ $a < 20; } or { let $x = 1; $x > 0; $a > 0; };
187+
"""
188+
189+
190+
Scenario: Variables which occur in a negation and are NOT PRESENT in a parent conjunction are local and unavailable in subsequent stages.
191+
Given connection open read transaction for database: typedb
192+
When get answers of typeql read query
193+
"""
194+
match
195+
let $a = 10;
196+
not { let $x = 1; $x > 10; };
197+
match
198+
let $b = $a + 2;
199+
"""
200+
Then uniquely identify answer concepts
201+
| b |
202+
| value:integer:12 |
203+
204+
Then typeql read query; fails with a message containing: "Invalid query containing unbound concept variable x"
205+
"""
206+
match
207+
let $a = 10;
208+
not { let $x = 1; $x > 10; };
209+
match
210+
let $y = $x + 2;
211+
"""
212+
213+
214+
Scenario: Variables which occur in a negation and ARE PRESENT elsewhere MUST BE BOUND in the parent conjunction
215+
Given connection open read transaction for database: typedb
216+
When get answers of typeql read query
217+
"""
218+
match
219+
let $x = 1;
220+
not { $x > 10; };
221+
match
222+
let $y = $x + 2;
223+
"""
224+
Then uniquely identify answer concepts
225+
| y |
226+
| value:integer:3 |
227+
228+
When get answers of typeql read query
229+
"""
230+
# Skip a level
231+
match
232+
let $x = 1;
233+
{ not { $x > 10; }; } or { not { $x < 0; }; };
234+
match
235+
let $y = $x + 2;
236+
"""
237+
Then uniquely identify answer concepts
238+
| y |
239+
| value:integer:3 |
240+
241+
242+
Then typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
243+
"""
244+
match
245+
not { let $x = 1; $x > 10; };
246+
let $y = $x + 2;
247+
"""
248+
249+
250+
Scenario: It is illegal to have variables are in a negation, NOT PRESENT in a parent conjunction, and present only in some branches of a sibling disjunction.
251+
Given connection open read transaction for database: typedb
252+
Then typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
253+
"""
254+
match
255+
let $a = 10;
256+
{ let $x = 1; $a > 5; } or { $a < 15; };
257+
not { $x > 10; };
258+
"""
259+
260+
261+
Scenario: It is illegal to have variables in two separate negations which are NOT BOUND in an ancestor conjunction.
262+
Given connection open read transaction for database: typedb
263+
When get answers of typeql read query
264+
"""
265+
match
266+
let $x = 1;
267+
not { $x > 10; };
268+
not { $x < 0; };
269+
let $y = $x + 2;
270+
"""
271+
Then uniquely identify answer concepts
272+
| y |
273+
| value:integer:3 |
274+
275+
Then typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
276+
"""
277+
match
278+
not { let $x = 1; $x > 10; };
279+
not { let $x = 2; $x < 0; };
280+
"""
281+
282+
Then typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
283+
"""
284+
# Skip a level
285+
match
286+
{ not { let $x = 1; $x > 10; }; } or
287+
{ not { let $x = 2; $x < 0; }; };
288+
match
289+
let $y = $x + 2;
290+
"""
291+
292+
293+
Scenario: Reassigning an argument to a return does not make it binding
294+
Given connection open read transaction for database: typedb
295+
When typeql read query; fails with a message containing: "The variable 'x' is required to be bound to a value before it's used"
296+
"""
297+
with fun ident($x: integer) -> integer:
298+
match let $y = $x;
299+
return first $y;
300+
301+
match
302+
let $x = ident($x);
303+
"""

0 commit comments

Comments
 (0)