|
2 | 2 | ## TypeQL Grammar and Language Library distributions for Rust
|
3 | 3 |
|
4 | 4 | Available through https://crates.io/crates/typeql.
|
5 |
| - |
6 |
| -## New Features |
7 |
| - |
8 |
| - |
9 |
| -- **TypeQL 3.0** |
10 |
| - |
11 |
| - User-defined functions and structs: |
12 |
| - ```typeql |
13 |
| - fun mean_salary($c: company) -> double? : |
14 |
| - match |
15 |
| - (company: $c, employee: $_) isa employment, has salary $s; |
16 |
| - return mean($s); |
17 |
| - ``` |
18 |
| - ```typeql |
19 |
| - struct dated_coordinate: |
20 |
| - longitude value double, |
21 |
| - latitude value double, |
22 |
| - date value datetime; |
23 |
| - ``` |
24 |
| - |
25 |
| - Query pipelines: |
26 |
| - ``` |
27 |
| - with fun costliest_printer($employee: employee) -> printer? : |
28 |
| - match |
29 |
| - ($printer, $employee) isa print_permission; |
30 |
| - $printer has cost_per_page $cost; |
31 |
| - sort $cost desc; |
32 |
| - return first($printer); |
33 |
| - match |
34 |
| - $printer isa printer, has office_number $n, has newly_installed true; |
35 |
| - $employee isa employee, has office_number $n; |
36 |
| - put ($employee, $printer) isa print_permission; |
37 |
| - match |
38 |
| - $high_cost_printer = costliest_printer($employee), has printer_name $name; |
39 |
| - not { $printer is $high_cost_printer; }; |
40 |
| - $employee has contact $address; |
41 |
| - insert |
42 |
| - $notice isa queued_email, has recipient $address, |
43 |
| - has content "Do you still need the printer " + $name + "?"; |
44 |
| - ``` |
45 |
| - |
46 |
| - New undefine syntax allows user to be more precise as to what is being undefined: |
47 |
| - ```typeql |
48 |
| - undefine |
49 |
| - owns age from person; |
50 |
| - @regex from first-name; |
51 |
| - as name from person owns first-name; |
52 |
| - ``` |
53 |
| - New, more concise delete syntax: |
54 |
| - ```typeql |
55 |
| - match $p isa person, has name $n; |
56 |
| - delete $n of $p; |
57 |
| - ``` |
58 |
| - |
59 |
| - Implement JSON-like string unescaping (closes #106). |
60 |
| - |
61 |
| - See [The TypeDB 3.0 Roadmap](<https://typedb.com/blog/typedb-3-roadmap>) for more details! |
62 |
| - |
63 |
| - |
64 |
| -- **[3.0] Change plays override from label to named_type to allow both scoped and not scoped labels** |
65 |
| - |
66 |
| - Previously, we could only use not scoped labels (names without scopes) in `as` of `plays`. However, it can cause troubles while reading the schema by a human eye: |
67 |
| - ``` |
68 |
| - define |
69 |
| - relation family relates father; |
70 |
| - relation fathership relates father; |
71 |
| - |
72 |
| - entity person plays family:father, plays fathership:father; |
73 |
| - |
74 |
| - # It is fine: we can't have another "relates father" in family or fathership |
75 |
| - relation subfamily sub family, relates subfather as father; |
76 |
| - relation subfathership sub fathership, relates subfather as father; |
77 |
| - |
78 |
| - # It creates more questions as subperson can play multiple `father`s |
79 |
| - entity subperson sub person, plays subfamily:subfather as father, plays subfathership:subfather as father; |
80 |
| - ``` |
81 |
| - |
82 |
| - This PR allows us to use both |
83 |
| - `entity subperson sub person, plays subfamily:subfather as family:father, plays subfathership:subfather as fathership:father;` |
84 |
| - and |
85 |
| - ` |
86 |
| - entity subperson sub person, plays subfamily:subfather as father, plays subfathership:subfather as father;` |
87 |
| - based on users' preferences. |
88 |
| - |
89 |
| - |
90 |
| -- **TypeQL 3 grammar enhancements** |
91 |
| - |
92 |
| - 1. New rich `fetch` syntax (see below). |
93 |
| - 2. Standardise the vocabulary of `pipeline`, `stage`, `clause`, `operator`. A _pipeline_ consists of _stages_. Each _stage_ may be an _operator_, which modifies the data stream without accessing the database (e.g. `count`, `mean($x)`), or a _clause,_ which may fetch data from the database to modify the stream (e.g. `match`, `fetch`). |
94 |
| - 3. `list()` stream reduce operator. |
95 |
| - 4. `$x in [$a, $b, $c]` and other list expressions now allowed in `in`-statements (previously stream-only) |
96 |
| - |
97 |
| - ### New `fetch` syntax sample |
98 |
| - |
99 |
| - ```php |
100 |
| - ... # incoming pipeline |
101 |
| - fetch { |
102 |
| - # Printing values directly from pipeline |
103 |
| - "key_1": $x, # var $x (from input stream) holds a value or list |
104 |
| - "key_2": <EXPR>, # <EXPR> is an expression like $x + $y |
105 |
| - |
106 |
| - # Inline attribute retrieval variations |
107 |
| - "key_3": $y.attr, # var $y holds an object with singleton attribute 'attr' |
108 |
| - "key_4": [ $y.attr ], # object var $y has multiple attributes 'attr' |
109 |
| - "key_5": $y.attr[], # object var $y has a list attribute 'attr' |
110 |
| - |
111 |
| - # Function call variations |
112 |
| - "key_6": my_fun1($x,$y), # function my_fun1 has single-return |
113 |
| - "key_7": [ my_fun2($x,$y) ], # function my_fun2 has stream-return |
114 |
| - |
115 |
| - # Match-fetch subqueries |
116 |
| - "key_8": [ |
117 |
| - match ...; |
118 |
| - fetch { |
119 |
| - "sub_key": $z, |
120 |
| - ... |
121 |
| - }; |
122 |
| - ] |
123 |
| - |
124 |
| - # Match-reduce-value subqueries |
125 |
| - "key_9": |
126 |
| - match ...; |
127 |
| - reduce agg($z); # agg could be, e.g., 'count', 'sum', or 'list' |
128 |
| - |
129 |
| - # Nested keys: Nothing stops you from nesting the above! |
130 |
| - "super_key": { |
131 |
| - "sub_key_1": $x, |
132 |
| - "sub_key_2": $y.attr, |
133 |
| - "sub_key_3": [ |
134 |
| - ... # some subquery |
135 |
| - ] |
136 |
| - } |
137 |
| - }; |
138 |
| - |
139 |
| - |
140 |
| - ``` |
141 |
| - |
142 |
| -- **Update syntax for reduce stages in pipelines** |
143 |
| - Update syntax for reduce stages in pipelines. Example: `reduce $max = max($of1), $sum = sum($of2) within ($group, $variables)` |
144 |
| - |
145 |
| - |
146 |
| -- **Implement full fetch specification** |
147 |
| - |
148 |
| - We refactor Fetch and Function behaviour, to allow any of the following Fetching patterns: |
149 |
| - ``` |
150 |
| - match |
151 |
| - ... |
152 |
| - fetch { |
153 |
| - // fetch a matched attribute, value, or type. Represented as a attribute/value/type or null (if the variable is optional). |
154 |
| - "single variable": $a, |
155 |
| - |
156 |
| - // attribute 'age' of $x. Must be `@card(0..1)` or `@card(1..1)`. Represented as an attribute or null. |
157 |
| - "single-card attributes": $x.age, |
158 |
| - |
159 |
| - // all attributes 'name' of $x. Can be any cardinality. |
160 |
| - "list higher-card attributes": [ $x.name ], |
161 |
| - |
162 |
| - // inline-computed expression value. Represented as a value. |
163 |
| - "single value expression": $a + 1, |
164 |
| - |
165 |
| - // an inline query with a 'return' block to select a *single* answer. Represented identically to a single variable or null. |
166 |
| - "single answer block": ( |
167 |
| - match |
168 |
| - $x has name $name; |
169 |
| - return first $name; |
170 |
| - ), |
171 |
| - |
172 |
| - // an inline query with a 'return' block to reduce to a *single* answer. Represented as a value or null |
173 |
| - "reduce answer block": ( |
174 |
| - match |
175 |
| - $x has name $name; |
176 |
| - return count($name); |
177 |
| - ), |
178 |
| - |
179 |
| - // an inline query that returns a stream of lists/tuples. Represented as list of lists. |
180 |
| - "list positional return block": [ |
181 |
| - match |
182 |
| - $x has name $n, |
183 |
| - has age $a; |
184 |
| - return { $n, $a }; |
185 |
| - ], |
186 |
| - |
187 |
| - // an inline query that returns stream of sub-documents. Represented as a list of objects. |
188 |
| - "list pipeline": [ |
189 |
| - match |
190 |
| - $x has name $n, |
191 |
| - has age $a; |
192 |
| - fetch { |
193 |
| - "name": $n |
194 |
| - }; |
195 |
| - ], |
196 |
| - |
197 |
| - // special syntax to fetch all attributes of a concept. Represented as an object, where keys are attribute type names and values are either lists (for >card(1)) or nullable values (for card(0..1) or card(1..1)) |
198 |
| - "all attributes": { $x.* } |
199 |
| - } |
200 |
| - ``` |
201 |
| - |
202 |
| - |
203 |
| -- **Implement require operator** |
204 |
| - |
205 |
| - Implement the 'require' clause: |
206 |
| - ``` |
207 |
| - match |
208 |
| - ... |
209 |
| - require $x, $y, $z; |
210 |
| - ``` |
211 |
| - Will filter the match output stream to ensure that the variable `$x, $y, $z` are all non-empty variables (if they are optional). |
212 |
| - |
213 |
| - |
214 |
| -- **Introduce Reduce keyword for stream reduction operations** |
215 |
| - |
216 |
| - We introduce the missing `reduce` keyword for operations like `min/max/count` aggregations, as well as `first()` and `check`. However, we do not require the `reduce` keyword for function return statements: |
217 |
| - |
218 |
| - ``` |
219 |
| - match |
220 |
| - ... |
221 |
| - reduce count($x); |
222 |
| - ``` |
223 |
| - in a function would be; |
224 |
| - ``` |
225 |
| - define |
226 |
| - fun test(...) -> long: |
227 |
| - match ... |
228 |
| - return count($x); |
229 |
| - ``` |
230 |
| - |
231 |
| - We also allow trailing commas throughout the grammar, though they are ignored, to allow the user to generate queries more simply: |
232 |
| - ``` |
233 |
| - match |
234 |
| - $x, isa person, has name $n, ... ; #equivalent to the user-friendly syntax: $x isa person, has name, ...; |
235 |
| - ``` |
236 |
| - |
237 |
| - |
238 |
| -- **Fill in some Display traits & fetch refactor for fetch *** |
239 |
| - |
240 |
| - We fill in missing Display and Pretty printing traits -- note Struct destructuring and Functions are still not implemented. |
241 |
| - |
242 |
| - We also add a new special syntax to fetch all attributes, since `attribute` is no longer a supertype of all attributes: |
243 |
| - ``` |
244 |
| - fetch { |
245 |
| - "attrs": { $x.* } |
246 |
| - } |
247 |
| - ``` |
248 |
| - |
249 |
| -- **Implement duration literal parsing** |
250 |
| - |
251 |
| - |
| 5 | +``` |
| 6 | +cargo add typeql@3.0.1 |
| 7 | +``` |
252 | 8 |
|
253 | 9 | ## Code Refactors
|
254 |
| -- **TypeQL syntax updates** |
255 |
| - Adds `let` keyword before assignments & moves the constraint on an `isa` to the end. E.g. `$x isa marriage ($a, $b)` |
256 |
| - |
257 |
| - |
258 |
| -- **Rename override to specialise. Remove specialisations for owns and plays** |
259 |
| - Rename override to specialise. Remove specialisations for owns and plays respecting the server's changes: https://github.com/typedb/typedb/pull/7157 |
260 |
| - |
261 |
| -- **Low hanging optimisations for TypeQL** |
262 |
| - Low hanging optimisations for TypeQL |
263 |
| - |
264 |
| - |
265 |
| -- **Make Is statement fields public** |
266 |
| - |
267 |
| - We make the `lhs` and `rhs` fields of the `Is` statement struct public for use in typedb core. |
268 |
| - |
269 |
| -- **Expose some extra fields in statements** |
270 |
| - Expose some more required fields. |
271 |
| - |
272 |
| - |
273 |
| -- **Update fields used by function builders in core to be public** |
274 |
| - Updates fields used by function builders in core to be public. |
275 |
| - |
| 10 | +- **Rename within to groupby** |
276 | 11 |
|
277 |
| - |
278 |
| -## Other Improvements |
279 |
| -- **Make iid field public** |
280 |
| - |
281 |
| -- **Update maven snapshot** |
282 |
| - |
283 |
| - We update the maven artifacts snapshot for build dependency test. |
284 |
| - |
285 |
| - |
286 |
| -- **Reorder fetch variants to prioritize the fetch stream for functions over the list of expressions** |
287 |
| - We reorder fetch variants to prioritize the fetch stream for functions over the list of expressions. The old ordering led to incorrect parsing of fetch statements with listed function calls. |
288 |
| - |
289 |
| - |
290 |
| -- **Commit generated Cargo.toml** |
291 |
| - |
292 |
| - We commit the generated cargo manifests so that `typeql` can be used as a cargo git dependency. |
293 |
| - |
294 |
| -- **Add unescape version for regex annotations** |
295 |
| - We add a separate `unescape` method for strings inside `regex` annotations to preserve regex escaped characters and unescape `"` quotes. |
296 |
| - |
297 |
| -- **autogenerated grammar visitor tests** |
| 12 | + We rename `within` to `groupby`, in better alignment with expected terminology. |
| 13 | + |
0 commit comments