1 .. -*- coding: utf-8 -*- |
|
2 |
|
3 .. _RQL: |
|
4 |
|
5 RQL syntax |
|
6 ---------- |
|
7 |
|
8 .. _RQLKeywords: |
|
9 |
|
10 Reserved keywords |
|
11 ~~~~~~~~~~~~~~~~~ |
|
12 |
|
13 :: |
|
14 |
|
15 AND, ASC, BEING, DELETE, DESC, DISTINCT, EXISTS, FALSE, GROUPBY, |
|
16 HAVING, ILIKE, INSERT, LIKE, LIMIT, NOT, NOW, NULL, OFFSET, |
|
17 OR, ORDERBY, SET, TODAY, TRUE, UNION, WHERE, WITH |
|
18 |
|
19 The keywords are not case sensitive. You should not use them when defining your |
|
20 schema, or as RQL variable names. |
|
21 |
|
22 |
|
23 .. _RQLCase: |
|
24 |
|
25 Case |
|
26 ~~~~ |
|
27 |
|
28 * Variables should be all upper-cased. |
|
29 |
|
30 * Relation should be all lower-cased and match exactly names of relations defined |
|
31 in the schema. |
|
32 |
|
33 * Entity types should start with an upper cased letter and be followed by at least |
|
34 a lower cased latter. |
|
35 |
|
36 |
|
37 .. _RQLVariables: |
|
38 |
|
39 Variables and typing |
|
40 ~~~~~~~~~~~~~~~~~~~~ |
|
41 |
|
42 Entities and values to browse and/or select are represented in the query by |
|
43 *variables* that must be written in capital letters. |
|
44 |
|
45 With RQL, we do not distinguish between entities and attributes. The value of an |
|
46 attribute is considered as an entity of a particular type (see below), linked to |
|
47 one (real) entity by a relation called the name of the attribute, where the |
|
48 entity is the subject and the attribute the object. |
|
49 |
|
50 The possible type(s) for each variable is derived from the schema according to |
|
51 the constraints expressed above and thanks to the relations between each |
|
52 variable. |
|
53 |
|
54 We can restrict the possible types for a variable using the special relation |
|
55 **is** in the restrictions. |
|
56 |
|
57 |
|
58 .. _VirtualRelations: |
|
59 |
|
60 Virtual relations |
|
61 ~~~~~~~~~~~~~~~~~ |
|
62 |
|
63 Those relations may only be used in RQL query but are not actual attributes of |
|
64 your entities. |
|
65 |
|
66 * `has_text`: relation to use to query the full text index (only for entities |
|
67 having fulltextindexed attributes). |
|
68 |
|
69 * `identity`: relation to use to tell that a RQL variable is the same as another |
|
70 when you've to use two different variables for querying purpose. On the |
|
71 opposite it's also useful together with the ``NOT`` operator to tell that two |
|
72 variables should not identify the same entity |
|
73 |
|
74 |
|
75 .. _RQLLiterals: |
|
76 |
|
77 Literal expressions |
|
78 ~~~~~~~~~~~~~~~~~~~ |
|
79 |
|
80 Bases types supported by RQL are those supported by yams schema. Literal values |
|
81 are expressed as explained below: |
|
82 |
|
83 * string should be between double or single quotes. If the value contains a |
|
84 quote, it should be preceded by a backslash '\\' |
|
85 |
|
86 * floats separator is dot '.' |
|
87 |
|
88 * boolean values are ``TRUE`` and ``FALSE`` keywords |
|
89 |
|
90 * date and time should be expressed as a string with ISO notation : YYYY/MM/DD |
|
91 [hh:mm], or using keywords ``TODAY`` and ``NOW`` |
|
92 |
|
93 You may also use the ``NULL`` keyword, meaning 'unspecified'. |
|
94 |
|
95 |
|
96 .. _RQLOperators: |
|
97 |
|
98 Operators |
|
99 ~~~~~~~~~ |
|
100 |
|
101 .. _RQLLogicalOperators: |
|
102 |
|
103 Logical operators |
|
104 ````````````````` |
|
105 :: |
|
106 |
|
107 AND, OR, NOT, ',' |
|
108 |
|
109 ',' is equivalent to 'AND' but with the smallest among the priority of logical |
|
110 operators (see :ref:`RQLOperatorsPriority`). |
|
111 |
|
112 .. _RQLMathematicalOperators: |
|
113 |
|
114 Mathematical operators |
|
115 `````````````````````` |
|
116 |
|
117 +----------+---------------------+-----------+--------+ |
|
118 | Operator | Description | Example | Result | |
|
119 +==========+=====================+===========+========+ |
|
120 | `+` | addition | 2 + 3 | 5 | |
|
121 +----------+---------------------+-----------+--------+ |
|
122 | `-` | subtraction | 2 - 3 | -1 | |
|
123 +----------+---------------------+-----------+--------+ |
|
124 | `*` | multiplication | 2 * 3 | 6 | |
|
125 +----------+---------------------+-----------+--------+ |
|
126 | / | division | 4 / 2 | 2 | |
|
127 +----------+---------------------+-----------+--------+ |
|
128 | % | modulo (remainder) | 5 % 4 | 1 | |
|
129 +----------+---------------------+-----------+--------+ |
|
130 | ^ | exponentiation | 2.0 ^ 3.0 | 8 | |
|
131 +----------+---------------------+-----------+--------+ |
|
132 | & | bitwise AND | 91 & 15 | 11 | |
|
133 +----------+---------------------+-----------+--------+ |
|
134 | `|` | bitwise OR | 32 | 3 | 35 | |
|
135 +----------+---------------------+-----------+--------+ |
|
136 | # | bitwise XOR | 17 # 5 | 20 | |
|
137 +----------+---------------------+-----------+--------+ |
|
138 | ~ | bitwise NOT | ~1 | -2 | |
|
139 +----------+---------------------+-----------+--------+ |
|
140 | << | bitwise shift left | 1 << 4 | 16 | |
|
141 +----------+---------------------+-----------+--------+ |
|
142 | >> | bitwise shift right | 8 >> 2 | 2 | |
|
143 +----------+---------------------+-----------+--------+ |
|
144 |
|
145 |
|
146 Notice integer division truncates results depending on the backend behaviour. For |
|
147 instance, postgresql does. |
|
148 |
|
149 |
|
150 .. _RQLComparisonOperators: |
|
151 |
|
152 Comparison operators |
|
153 ```````````````````` |
|
154 :: |
|
155 |
|
156 =, !=, <, <=, >=, >, IN |
|
157 |
|
158 |
|
159 The syntax to use comparison operators is: |
|
160 |
|
161 `VARIABLE attribute <operator> VALUE` |
|
162 |
|
163 The `=` operator is the default operator and can be omitted, i.e. : |
|
164 |
|
165 `VARIABLE attribute = VALUE` |
|
166 |
|
167 is equivalent to |
|
168 |
|
169 `VARIABLE attribute VALUE` |
|
170 |
|
171 |
|
172 The operator `IN` provides a list of possible values: |
|
173 |
|
174 .. sourcecode:: sql |
|
175 |
|
176 Any X WHERE X name IN ('chauvat', 'fayolle', 'di mascio', 'thenault') |
|
177 |
|
178 |
|
179 .. _RQLStringOperators: |
|
180 |
|
181 String operators |
|
182 ```````````````` |
|
183 :: |
|
184 |
|
185 LIKE, ILIKE, ~=, REGEXP |
|
186 |
|
187 The ``LIKE`` string operator can be used with the special character `%` in |
|
188 a string as wild-card: |
|
189 |
|
190 .. sourcecode:: sql |
|
191 |
|
192 -- match every entity whose name starts with 'Th' |
|
193 Any X WHERE X name ~= 'Th%' |
|
194 -- match every entity whose name endswith 'lt' |
|
195 Any X WHERE X name LIKE '%lt' |
|
196 -- match every entity whose name contains a 'l' and a 't' |
|
197 Any X WHERE X name LIKE '%l%t%' |
|
198 |
|
199 ``ILIKE`` is the case insensitive version of ``LIKE``. It's not |
|
200 available on all backend (e.g. sqlite doesn't support it). If not available for |
|
201 your backend, ``ILIKE`` will behave like ``LIKE``. |
|
202 |
|
203 `~=` is a shortcut version of ``ILIKE``, or of ``LIKE`` when the |
|
204 former is not available on the back-end. |
|
205 |
|
206 |
|
207 The ``REGEXP`` is an alternative to ``LIKE`` that supports POSIX |
|
208 regular expressions: |
|
209 |
|
210 .. sourcecode:: sql |
|
211 |
|
212 -- match entities whose title starts with a digit |
|
213 Any X WHERE X title REGEXP "^[0-9].*" |
|
214 |
|
215 |
|
216 The underlying SQL operator used is back-end-dependent : |
|
217 |
|
218 - the ``~`` operator is used for postgresql, |
|
219 - the ``REGEXP`` operator for mysql and sqlite. |
|
220 |
|
221 Other back-ends are not supported yet. |
|
222 |
|
223 |
|
224 .. _RQLOperatorsPriority: |
|
225 |
|
226 Operators priority |
|
227 `````````````````` |
|
228 |
|
229 #. `(`, `)` |
|
230 #. `^`, `<<`, `>>` |
|
231 #. `*`, `/`, `%`, `&` |
|
232 #. `+`, `-`, `|`, `#` |
|
233 #. `NOT` |
|
234 #. `AND` |
|
235 #. `OR` |
|
236 #. `,` |
|
237 |
|
238 |
|
239 .. _RQLSearchQuery: |
|
240 |
|
241 Search Query |
|
242 ~~~~~~~~~~~~ |
|
243 |
|
244 Simplified grammar of search query: :: |
|
245 |
|
246 [ `DISTINCT`] `Any` V1 (, V2) \* |
|
247 [ `GROUPBY` V1 (, V2) \*] [ `ORDERBY` <orderterms>] |
|
248 [ `LIMIT` <value>] [ `OFFSET` <value>] |
|
249 [ `WHERE` <triplet restrictions>] |
|
250 [ `WITH` V1 (, V2)\* BEING (<query>)] |
|
251 [ `HAVING` <other restrictions>] |
|
252 [ `UNION` <query>] |
|
253 |
|
254 Selection |
|
255 ````````` |
|
256 |
|
257 The fist occuring clause is the selection of terms that should be in the result |
|
258 set. Terms may be variable, literals, function calls, arithmetic, etc. and each |
|
259 term is separated by a comma. |
|
260 |
|
261 There will be as much column in the result set as term in this clause, respecting |
|
262 order. |
|
263 |
|
264 Syntax for function call is somewhat intuitive, for instance: |
|
265 |
|
266 .. sourcecode:: sql |
|
267 |
|
268 Any UPPER(N) WHERE P firstname N |
|
269 |
|
270 |
|
271 Grouping and aggregating |
|
272 ```````````````````````` |
|
273 |
|
274 The ``GROUPBY`` keyword is followed by a list of terms on which results |
|
275 should be grouped. They are usually used with aggregate functions, responsible to |
|
276 aggregate values for each group (see :ref:`RQLAggregateFunctions`). |
|
277 |
|
278 For grouped queries, all selected variables must be either aggregated (i.e. used |
|
279 by an aggregate function) or grouped (i.e. listed in the ``GROUPBY`` |
|
280 clause). |
|
281 |
|
282 |
|
283 Sorting |
|
284 ``````` |
|
285 |
|
286 The ``ORDERBY`` keyword if followed by the definition of the selection |
|
287 order: variable or column number followed by sorting method (``ASC``, |
|
288 ``DESC``), ``ASC`` being the default. If the sorting method is not |
|
289 specified, then the sorting is ascendant (`ASC`). |
|
290 |
|
291 |
|
292 Pagination |
|
293 `````````` |
|
294 |
|
295 The ``LIMIT`` and ``OFFSET`` keywords may be respectively used to |
|
296 limit the number of results and to tell from which result line to start (for |
|
297 instance, use `LIMIT 20` to get the first 20 results, then `LIMIT 20 OFFSET 20` |
|
298 to get the next 20. |
|
299 |
|
300 |
|
301 Restrictions |
|
302 ```````````` |
|
303 |
|
304 The ``WHERE`` keyword introduce one of the "main" part of the query, where |
|
305 you "define" variables and add some restrictions telling what you're interested |
|
306 in. |
|
307 |
|
308 It's a list of triplets "subject relation object", e.g. `V1 relation |
|
309 (V2 | <static value>)`. Triplets are separated using :ref:`RQLLogicalOperators`. |
|
310 |
|
311 .. note:: |
|
312 |
|
313 About the negation operator (``NOT``): |
|
314 |
|
315 * ``NOT X relation Y`` is equivalent to ``NOT EXISTS(X relation Y)`` |
|
316 |
|
317 * ``Any X WHERE NOT X owned_by U`` means "entities that have no relation |
|
318 ``owned_by``". |
|
319 |
|
320 * ``Any X WHERE NOT X owned_by U, U login "syt"`` means "the entity have no |
|
321 relation ``owned_by`` with the user syt". They may have a relation "owned_by" |
|
322 with another user. |
|
323 |
|
324 In this clause, you can also use ``EXISTS`` when you want to know if some |
|
325 expression is true and do not need the complete set of elements that make it |
|
326 true. Testing for existence is much faster than fetching the complete set of |
|
327 results, especially when you think about using ``OR`` against several expressions. For instance |
|
328 if you want to retrieve versions which are in state "ready" or tagged by |
|
329 "priority", you should write : |
|
330 |
|
331 .. sourcecode:: sql |
|
332 |
|
333 Any X ORDERBY PN,N |
|
334 WHERE X num N, X version_of P, P name PN, |
|
335 EXISTS(X in_state S, S name "ready") |
|
336 OR EXISTS(T tags X, T name "priority") |
|
337 |
|
338 not |
|
339 |
|
340 .. sourcecode:: sql |
|
341 |
|
342 Any X ORDERBY PN,N |
|
343 WHERE X num N, X version_of P, P name PN, |
|
344 (X in_state S, S name "ready") |
|
345 OR (T tags X, T name "priority") |
|
346 |
|
347 Both queries aren't at all equivalent : |
|
348 |
|
349 * the former will retrieve all versions, then check for each one which are in the |
|
350 matching state of or tagged by the expected tag, |
|
351 |
|
352 * the later will retrieve all versions, state and tags (cartesian product!), |
|
353 compute join and then exclude each row which are in the matching state or |
|
354 tagged by the expected tag. This implies that you won't get any result if the |
|
355 in_state or tag tables are empty (ie there is no such relation in the |
|
356 application). This is usually NOT what you want. |
|
357 |
|
358 Another common case where you may want to use ``EXISTS`` is when you |
|
359 find yourself using ``DISTINCT`` at the beginning of your query to |
|
360 remove duplicate results. The typical case is when you have a |
|
361 multivalued relation such as Version version_of Project and you want |
|
362 to retrieve projects which have a version: |
|
363 |
|
364 .. sourcecode:: sql |
|
365 |
|
366 Any P WHERE V version_of P |
|
367 |
|
368 will return each project number of versions times. So you may be |
|
369 tempted to use: |
|
370 |
|
371 .. sourcecode:: sql |
|
372 |
|
373 DISTINCT ANY P WHERE V version_of P |
|
374 |
|
375 This will work, but is not efficient, as it will use the ``SELECT |
|
376 DISTINCT`` SQL predicate, which needs to retrieve all projects, then |
|
377 sort them and discard duplicates, which can have a very high cost for |
|
378 large result sets. So the best way to write this is: |
|
379 |
|
380 .. sourcecode:: sql |
|
381 |
|
382 ANY P WHERE EXISTS V version_of P |
|
383 |
|
384 |
|
385 You can also use the question mark (`?`) to mark optional relations. This allows |
|
386 you to select entities related **or not** to another. It is a similar concept |
|
387 to `Left outer join`_: |
|
388 |
|
389 the result of a left outer join (or simply left join) for table A and B |
|
390 always contains all records of the "left" table (A), even if the |
|
391 join-condition does not find any matching record in the "right" table (B). |
|
392 |
|
393 You must use the `?` behind a variable to specify that the relation to |
|
394 that variable is optional. For instance: |
|
395 |
|
396 - Bugs of a project attached or not to a version |
|
397 |
|
398 .. sourcecode:: sql |
|
399 |
|
400 Any X, V WHERE X concerns P, P eid 42, X corrected_in V? |
|
401 |
|
402 You will get a result set containing all the project's tickets, with either the |
|
403 version in which it's fixed or None for tickets not related to a version. |
|
404 |
|
405 |
|
406 - All cards and the project they document if any |
|
407 |
|
408 .. sourcecode:: sql |
|
409 |
|
410 Any C, P WHERE C is Card, P? documented_by C |
|
411 |
|
412 Notice you may also use outer join: |
|
413 |
|
414 - on the RHS of attribute relation, e.g. |
|
415 |
|
416 .. sourcecode:: sql |
|
417 |
|
418 Any X WHERE X ref XR, Y name XR? |
|
419 |
|
420 so that Y is outer joined on X by ref/name attributes comparison |
|
421 |
|
422 |
|
423 - on any side of an ``HAVING`` expression, e.g. |
|
424 |
|
425 .. sourcecode:: sql |
|
426 |
|
427 Any X WHERE X creation_date XC, Y creation_date YC |
|
428 HAVING YEAR(XC)=YEAR(YC)? |
|
429 |
|
430 so that Y is outer joined on X by comparison of the year extracted from their |
|
431 creation date. |
|
432 |
|
433 .. sourcecode:: sql |
|
434 |
|
435 Any X WHERE X creation_date XC, Y creation_date YC |
|
436 HAVING YEAR(XC)?=YEAR(YC) |
|
437 |
|
438 would outer join X on Y instead. |
|
439 |
|
440 |
|
441 Having restrictions |
|
442 ``````````````````` |
|
443 |
|
444 The ``HAVING`` clause, as in SQL, may be used to restrict a query |
|
445 according to value returned by an aggregate function, e.g. |
|
446 |
|
447 .. sourcecode:: sql |
|
448 |
|
449 Any X GROUPBY X WHERE X relation Y HAVING COUNT(Y) > 10 |
|
450 |
|
451 It may however be used for something else: In the ``WHERE`` clause, we are |
|
452 limited to triplet expressions, so some things may not be expressed there. Let's |
|
453 take an example : if you want to get people whose upper-cased first name equals to |
|
454 another person upper-cased first name. There is no proper way to express this |
|
455 using triplet, so you should use something like: |
|
456 |
|
457 .. sourcecode:: sql |
|
458 |
|
459 Any X WHERE X firstname XFN, Y firstname YFN, NOT X identity Y HAVING UPPER(XFN) = UPPER(YFN) |
|
460 |
|
461 Another example: imagine you want person born in 2000: |
|
462 |
|
463 .. sourcecode:: sql |
|
464 |
|
465 Any X WHERE X birthday XB HAVING YEAR(XB) = 2000 |
|
466 |
|
467 Notice that while we would like this to work without the HAVING clause, this |
|
468 can't be currently be done because it introduces an ambiguity in RQL's grammar |
|
469 that can't be handled by Yapps_, the parser's generator we're using. |
|
470 |
|
471 |
|
472 Sub-queries |
|
473 ``````````` |
|
474 |
|
475 The ``WITH`` keyword introduce sub-queries clause. Each sub-query has the |
|
476 form: |
|
477 |
|
478 V1(,V2) BEING (rql query) |
|
479 |
|
480 Variables at the left of the ``BEING`` keyword defines into which |
|
481 variables results from the sub-query will be mapped to into the outer query. |
|
482 Sub-queries are separated from each other using a comma. |
|
483 |
|
484 Let's say we want to retrieve for each project its number of versions and its |
|
485 number of tickets. Due to the nature of relational algebra behind the scene, this |
|
486 can't be achieved using a single query. You have to write something along the |
|
487 line of: |
|
488 |
|
489 .. sourcecode:: sql |
|
490 |
|
491 Any X, VC, TC WHERE X identity XX |
|
492 WITH X, VC BEING (Any X, COUNT(V) GROUPBY X WHERE V version_of X), |
|
493 XX, TC BEING (Any X, COUNT(T) GROUPBY X WHERE T ticket_of X) |
|
494 |
|
495 Notice that we can't reuse a same variable name as alias for two different |
|
496 sub-queries, hence the usage of 'X' and 'XX' in this example, which are then |
|
497 unified using the special `identity` relation (see :ref:`VirtualRelations`). |
|
498 |
|
499 .. warning:: |
|
500 |
|
501 Sub-queries define a new variable scope, so even if a variable has the same name |
|
502 in the outer query and in the sub-query, they technically **aren't** the same |
|
503 variable. So: |
|
504 |
|
505 .. sourcecode:: sql |
|
506 |
|
507 Any W, REF WITH W, REF BEING |
|
508 (Any W, REF WHERE W is Workcase, W ref REF, |
|
509 W concerned_by D, D name "Logilab") |
|
510 |
|
511 could be written: |
|
512 |
|
513 .. sourcecode:: sql |
|
514 |
|
515 Any W, REF WITH W, REF BEING |
|
516 (Any W1, REF1 WHERE W1 is Workcase, W1 ref REF1, |
|
517 W1 concerned_by D, D name "Logilab") |
|
518 |
|
519 Also, when a variable is coming from a sub-query, you currently can't reference |
|
520 its attribute or inlined relations in the outer query, you've to fetch them in |
|
521 the sub-query. For instance, let's say we want to sort by project name in our |
|
522 first example, we would have to write: |
|
523 |
|
524 .. sourcecode:: sql |
|
525 |
|
526 |
|
527 Any X, VC, TC ORDERBY XN WHERE X identity XX |
|
528 WITH X, XN, VC BEING (Any X, COUNT(V) GROUPBY X,XN WHERE V version_of X, X name XN), |
|
529 XX, TC BEING (Any X, COUNT(T) GROUPBY X WHERE T ticket_of X) |
|
530 |
|
531 instead of: |
|
532 |
|
533 .. sourcecode:: sql |
|
534 |
|
535 Any X, VC, TC ORDERBY XN WHERE X identity XX, X name XN, |
|
536 WITH X, XN, VC BEING (Any X, COUNT(V) GROUPBY X WHERE V version_of X), |
|
537 XX, TC BEING (Any X, COUNT(T) GROUPBY X WHERE T ticket_of X) |
|
538 |
|
539 which would result in a SQL execution error. |
|
540 |
|
541 |
|
542 Union |
|
543 ````` |
|
544 |
|
545 You may get a result set containing the concatenation of several queries using |
|
546 the ``UNION``. The selection of each query should have the same number of |
|
547 columns. |
|
548 |
|
549 .. sourcecode:: sql |
|
550 |
|
551 (Any X, XN WHERE X is Person, X surname XN) UNION (Any X,XN WHERE X is Company, X name XN) |
|
552 |
|
553 |
|
554 .. _RQLFunctions: |
|
555 |
|
556 Available functions |
|
557 ~~~~~~~~~~~~~~~~~~~ |
|
558 |
|
559 Below is the list of aggregate and transformation functions that are supported |
|
560 nativly by the framework. Notice that cubes may define additional functions. |
|
561 |
|
562 .. _RQLAggregateFunctions: |
|
563 |
|
564 Aggregate functions |
|
565 ``````````````````` |
|
566 +------------------------+----------------------------------------------------------+ |
|
567 | ``COUNT(Any)`` | return the number of rows | |
|
568 +------------------------+----------------------------------------------------------+ |
|
569 | ``MIN(Any)`` | return the minimum value | |
|
570 +------------------------+----------------------------------------------------------+ |
|
571 | ``MAX(Any)`` | return the maximum value | |
|
572 +------------------------+----------------------------------------------------------+ |
|
573 | ``AVG(Any)`` | return the average value | |
|
574 +------------------------+----------------------------------------------------------+ |
|
575 | ``SUM(Any)`` | return the sum of values | |
|
576 +------------------------+----------------------------------------------------------+ |
|
577 | ``COMMA_JOIN(String)`` | return each value separated by a comma (for string only) | |
|
578 +------------------------+----------------------------------------------------------+ |
|
579 |
|
580 All aggregate functions above take a single argument. Take care some aggregate |
|
581 functions (e.g. ``MAX``, ``MIN``) may return `None` if there is no |
|
582 result row. |
|
583 |
|
584 .. _RQLStringFunctions: |
|
585 |
|
586 String transformation functions |
|
587 ``````````````````````````````` |
|
588 |
|
589 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
590 | ``UPPER(String)`` | upper case the string | |
|
591 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
592 | ``LOWER(String)`` | lower case the string | |
|
593 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
594 | ``LENGTH(String)`` | return the length of the string | |
|
595 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
596 | ``SUBSTRING(String, start, length)`` | extract from the string a string starting at given index and of | |
|
597 | | given length | |
|
598 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
599 | ``LIMIT_SIZE(String, max size)`` | if the length of the string is greater than given max size, | |
|
600 | | strip it and add ellipsis ("..."). The resulting string will | |
|
601 | | hence have max size + 3 characters | |
|
602 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
603 | ``TEXT_LIMIT_SIZE(String, format, max size)`` | similar to the above, but allow to specify the MIME type of the | |
|
604 | | text contained by the string. Supported formats are text/html, | |
|
605 | | text/xhtml and text/xml. All others will be considered as plain | |
|
606 | | text. For non plain text format, sgml tags will be first removed| |
|
607 | | before limiting the string. | |
|
608 +-----------------------------------------------+-----------------------------------------------------------------+ |
|
609 |
|
610 .. _RQLDateFunctions: |
|
611 |
|
612 Date extraction functions |
|
613 ````````````````````````` |
|
614 |
|
615 +----------------------+----------------------------------------+ |
|
616 | ``YEAR(Date)`` | return the year of a date or datetime | |
|
617 +----------------------+----------------------------------------+ |
|
618 | ``MONTH(Date)`` | return the month of a date or datetime | |
|
619 +----------------------+----------------------------------------+ |
|
620 | ``DAY(Date)`` | return the day of a date or datetime | |
|
621 +----------------------+----------------------------------------+ |
|
622 | ``HOUR(Datetime)`` | return the hours of a datetime | |
|
623 +----------------------+----------------------------------------+ |
|
624 | ``MINUTE(Datetime)`` | return the minutes of a datetime | |
|
625 +----------------------+----------------------------------------+ |
|
626 | ``SECOND(Datetime)`` | return the seconds of a datetime | |
|
627 +----------------------+----------------------------------------+ |
|
628 | ``WEEKDAY(Date)`` | return the day of week of a date or | |
|
629 | | datetime. Sunday == 1, Saturday == 7. | |
|
630 +----------------------+----------------------------------------+ |
|
631 |
|
632 .. _RQLOtherFunctions: |
|
633 |
|
634 Other functions |
|
635 ``````````````` |
|
636 +-------------------+--------------------------------------------------------------------+ |
|
637 | ``ABS(num)`` | return the absolute value of a number | |
|
638 +-------------------+--------------------------------------------------------------------+ |
|
639 | ``RANDOM()`` | return a pseudo-random value from 0.0 to 1.0 | |
|
640 +-------------------+--------------------------------------------------------------------+ |
|
641 | ``FSPATH(X)`` | expect X to be an attribute whose value is stored in a | |
|
642 | | :class:`BFSStorage` and return its path on the file system | |
|
643 +-------------------+--------------------------------------------------------------------+ |
|
644 | ``FTIRANK(X)`` | expect X to be an entity used in a has_text relation, and return a | |
|
645 | | number corresponding to the rank order of each resulting entity | |
|
646 +-------------------+--------------------------------------------------------------------+ |
|
647 | ``CAST(Type, X)`` | expect X to be an attribute and return it casted into the given | |
|
648 | | final type | |
|
649 +-------------------+--------------------------------------------------------------------+ |
|
650 |
|
651 |
|
652 .. _RQLExamples: |
|
653 |
|
654 Examples |
|
655 ~~~~~~~~ |
|
656 |
|
657 - *Search for the object of identifier 53* |
|
658 |
|
659 .. sourcecode:: sql |
|
660 |
|
661 Any X WHERE X eid 53 |
|
662 |
|
663 - *Search material such as comics, owned by syt and available* |
|
664 |
|
665 .. sourcecode:: sql |
|
666 |
|
667 Any X WHERE X is Document, |
|
668 X occurence_of F, F class C, C name 'Comics', |
|
669 X owned_by U, U login 'syt', |
|
670 X available TRUE |
|
671 |
|
672 - *Looking for people working for eurocopter interested in training* |
|
673 |
|
674 .. sourcecode:: sql |
|
675 |
|
676 Any P WHERE P is Person, P work_for S, S name 'Eurocopter', |
|
677 P interested_by T, T name 'training' |
|
678 |
|
679 - *Search note less than 10 days old written by jphc or ocy* |
|
680 |
|
681 .. sourcecode:: sql |
|
682 |
|
683 Any N WHERE N is Note, N written_on D, D day> (today -10), |
|
684 N written_by P, P name 'jphc' or P name 'ocy' |
|
685 |
|
686 - *Looking for people interested in training or living in Paris* |
|
687 |
|
688 .. sourcecode:: sql |
|
689 |
|
690 Any P WHERE P is Person, EXISTS(P interested_by T, T name 'training') OR |
|
691 (P city 'Paris') |
|
692 |
|
693 - *The surname and firstname of all people* |
|
694 |
|
695 .. sourcecode:: sql |
|
696 |
|
697 Any N, P WHERE X is Person, X name N, X firstname P |
|
698 |
|
699 Note that the selection of several entities generally force |
|
700 the use of "Any" because the type specification applies otherwise |
|
701 to all the selected variables. We could write here |
|
702 |
|
703 .. sourcecode:: sql |
|
704 |
|
705 String N, P WHERE X is Person, X name N, X first_name P |
|
706 |
|
707 |
|
708 Note: You can not specify several types with * ... where X is FirstType or X is SecondType*. |
|
709 To specify several types explicitly, you have to do |
|
710 |
|
711 |
|
712 .. sourcecode:: sql |
|
713 |
|
714 Any X WHERE X is IN (FirstType, SecondType) |
|
715 |
|
716 |
|
717 .. _RQLInsertQuery: |
|
718 |
|
719 Insertion query |
|
720 ~~~~~~~~~~~~~~~ |
|
721 |
|
722 `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments> |
|
723 [ `WHERE` <restriction>] |
|
724 |
|
725 :assignments: |
|
726 list of relations to assign in the form `V1 relationship V2 | <static value>` |
|
727 |
|
728 The restriction can define variables used in assignments. |
|
729 |
|
730 Caution, if a restriction is specified, the insertion is done for |
|
731 *each line result returned by the restriction*. |
|
732 |
|
733 - *Insert a new person named 'foo'* |
|
734 |
|
735 .. sourcecode:: sql |
|
736 |
|
737 INSERT Person X: X name 'foo' |
|
738 |
|
739 - *Insert a new person named 'foo', another called 'nice' and a 'friend' relation |
|
740 between them* |
|
741 |
|
742 .. sourcecode:: sql |
|
743 |
|
744 INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y |
|
745 |
|
746 - *Insert a new person named 'foo' and a 'friend' relation with an existing |
|
747 person called 'nice'* |
|
748 |
|
749 .. sourcecode:: sql |
|
750 |
|
751 INSERT Person X: X name 'foo', X friend Y WHERE Y name 'nice' |
|
752 |
|
753 .. _RQLSetQuery: |
|
754 |
|
755 Update and relation creation queries |
|
756 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
757 |
|
758 `SET` <assignements> |
|
759 [ `WHERE` <restriction>] |
|
760 |
|
761 Caution, if a restriction is specified, the update is done *for |
|
762 each result line returned by the restriction*. |
|
763 |
|
764 - *Renaming of the person named 'foo' to 'bar' with the first name changed* |
|
765 |
|
766 .. sourcecode:: sql |
|
767 |
|
768 SET X name 'bar', X firstname 'original' WHERE X is Person, X name 'foo' |
|
769 |
|
770 - *Insert a relation of type 'know' between objects linked by |
|
771 the relation of type 'friend'* |
|
772 |
|
773 .. sourcecode:: sql |
|
774 |
|
775 SET X know Y WHERE X friend Y |
|
776 |
|
777 |
|
778 .. _RQLDeleteQuery: |
|
779 |
|
780 Deletion query |
|
781 ~~~~~~~~~~~~~~ |
|
782 |
|
783 `DELETE` (<entity type> V) | (V1 relation v2 ),... |
|
784 [ `WHERE` <restriction>] |
|
785 |
|
786 Caution, if a restriction is specified, the deletion is made *for |
|
787 each line result returned by the restriction*. |
|
788 |
|
789 - *Deletion of the person named 'foo'* |
|
790 |
|
791 .. sourcecode:: sql |
|
792 |
|
793 DELETE Person X WHERE X name 'foo' |
|
794 |
|
795 - *Removal of all relations of type 'friend' from the person named 'foo'* |
|
796 |
|
797 .. sourcecode:: sql |
|
798 |
|
799 DELETE X friend Y WHERE X is Person, X name 'foo' |
|
800 |
|
801 |
|
802 .. _Yapps: http://theory.stanford.edu/~amitp/yapps/ |
|
803 .. _Left outer join: http://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join |
|
804 |
|