|
1 |
|
2 |
|
3 Implementation |
|
4 -------------- |
|
5 |
|
6 BNF grammar |
|
7 ~~~~~~~~~~~ |
|
8 |
|
9 The terminal elements are in capital letters, non-terminal in lowercase. |
|
10 The value of the terminal elements (between quotes) is a Python regular |
|
11 expression. |
|
12 :: |
|
13 |
|
14 statement ::= (select | delete | insert | update) ';' |
|
15 |
|
16 |
|
17 # select specific rules |
|
18 select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort? |
|
19 |
|
20 selected_terms ::= expression ( ',' expression)* |
|
21 |
|
22 group ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)* |
|
23 |
|
24 sort ::= 'ORDERBY' sort_term ( ',' sort_term)* |
|
25 |
|
26 sort_term ::= VARIABLE sort_method =? |
|
27 |
|
28 sort_method ::= 'ASC' | 'DESC' |
|
29 |
|
30 |
|
31 # delete specific rules |
|
32 delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction? |
|
33 |
|
34 |
|
35 # insert specific rules |
|
36 insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction? |
|
37 |
|
38 |
|
39 # update specific rules |
|
40 update ::= 'SET' relations_declaration restriction |
|
41 |
|
42 |
|
43 # common rules |
|
44 variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)* |
|
45 |
|
46 relations_declaration ::= simple_relation (',' simple_relation)* |
|
47 |
|
48 simple_relation ::= VARIABLE R_TYPE expression |
|
49 |
|
50 restriction ::= 'WHERE' relations |
|
51 |
|
52 relations ::= relation (LOGIC_OP relation)* |
|
53 | '(' relations')' |
|
54 |
|
55 relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression |
|
56 | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')' |
|
57 |
|
58 expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const) * |
|
59 | '(' expression ')' |
|
60 |
|
61 var_or_func_or_const ::= VARIABLE | function | constant |
|
62 |
|
63 function ::= FUNCTION '(' expression ( ',' expression) * ')' |
|
64 |
|
65 constant ::= KEYWORD | STRING | FLOAT | INT |
|
66 |
|
67 # tokens |
|
68 LOGIC_OP ::= ',' | 'OR' | 'AND' |
|
69 MATH_OP ::= '+' | '-' | '/' | '*' |
|
70 COMP_OP ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' |
|
71 |
|
72 FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER' |
|
73 |
|
74 VARIABLE ::= '[A-Z][A-Z0-9]*' |
|
75 E_TYPE ::= '[A-Z]\w*' |
|
76 R_TYPE ::= '[a-z_]+' |
|
77 |
|
78 KEYWORD ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW' |
|
79 STRING ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"' |
|
80 FLOAT ::= '\d+\.\d*' |
|
81 INT ::= '\d+' |
|
82 |
|
83 |
|
84 Internal representation (syntactic tree) |
|
85 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
86 |
|
87 The tree research does not contain the selected variables |
|
88 (e.g. there is only what follows "WHERE"). |
|
89 |
|
90 The insertion tree does not contain the variables inserted or relations |
|
91 defined on these variables (e.g. there is only what follows "WHERE"). |
|
92 |
|
93 The removal tree does not contain the deleted variables and relations |
|
94 (e.g. there is only what follows the "WHERE"). |
|
95 |
|
96 The update tree does not contain the variables and relations updated |
|
97 (e.g. there is only what follows the "WHERE"). |
|
98 |
|
99 :: |
|
100 |
|
101 Select ((Relationship | And | Or)?, Group?, Sort?) |
|
102 Insert (Relations | And | Or)? |
|
103 Delete (Relationship | And | Or)? |
|
104 Update (Relations | And | Or)? |
|
105 |
|
106 And ((Relationship | And | Or), (Relationship | And | Or)) |
|
107 Or ((Relationship | And | Or), (Relationship | And | Or)) |
|
108 |
|
109 Relationship ((VariableRef, Comparison)) |
|
110 |
|
111 Comparison ((Function | MathExpression | Keyword | Constant | VariableRef) +) |
|
112 |
|
113 Function (()) |
|
114 MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef)) |
|
115 |
|
116 Group (VariableRef +) |
|
117 Sort (SortTerm +) |
|
118 SortTerm (VariableRef +) |
|
119 |
|
120 VariableRef () |
|
121 Variable () |
|
122 Keyword () |
|
123 Constant () |
|
124 |
|
125 |
|
126 Known limitations |
|
127 ~~~~~~~~~~~~~~~~~ |
|
128 |
|
129 - The current implementation does not support linking two relations of type 'is' |
|
130 with an OR. I do not think that the negation is supported on this type of |
|
131 relation (XXX to be confirmed). |
|
132 |
|
133 - missing COALESCE and certainly other things... |
|
134 |
|
135 - writing an rql query requires knowledge of the used schema (with real relation |
|
136 names and entities, not those viewed in the user interface). On the other |
|
137 hand, we cannot really bypass that, and it is the job of a user interface to |
|
138 hide the RQL. |
|
139 |
|
140 |
|
141 Topics |
|
142 ~~~~~~ |
|
143 |
|
144 It would be convenient to express the schema matching |
|
145 relations (non-recursive rules):: |
|
146 |
|
147 Document class Type <-> Document occurence_of Fiche class Type |
|
148 Sheet class Type <-> Form collection Collection class Type |
|
149 |
|
150 Therefore 1. becomes:: |
|
151 |
|
152 Document X where |
|
153 X class C, C name 'Cartoon' |
|
154 X owned_by U, U login 'syt' |
|
155 X available true |
|
156 |
|
157 I'm not sure that we should handle this at RQL level ... |
|
158 |
|
159 There should also be a special relation 'anonymous'. |