108 def test_base_var(self): |
108 def test_base_var(self): |
109 constraint = ('X in_state S, U in_group G, P require_state S,' |
109 constraint = ('X in_state S, U in_group G, P require_state S,' |
110 'P name "read", P require_group G') |
110 'P name "read", P require_group G') |
111 rqlst = parse('Card C') |
111 rqlst = parse('Card C') |
112 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}) |
112 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}) |
113 self.failUnlessEqual(rqlst.as_string(), |
113 self.assertEqual(rqlst.as_string(), |
114 u"Any C WHERE C is Card, B eid %(D)s, " |
114 u"Any C WHERE C is Card, B eid %(D)s, " |
115 "EXISTS(C in_state A, B in_group E, F require_state A, " |
115 "EXISTS(C in_state A, B in_group E, F require_state A, " |
116 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission)") |
116 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission)") |
117 |
117 |
118 def test_multiple_var(self): |
118 def test_multiple_var(self): |
119 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
119 card_constraint = ('X in_state S, U in_group G, P require_state S,' |
120 'P name "read", P require_group G') |
120 'P name "read", P require_group G') |
121 affaire_constraints = ('X ref LIKE "PUBLIC%"', 'U in_group G, G name "public"') |
121 affaire_constraints = ('X ref LIKE "PUBLIC%"', 'U in_group G, G name "public"') |
122 kwargs = {'u':2} |
122 kwargs = {'u':2} |
123 rqlst = parse('Any S WHERE S documented_by C, C eid %(u)s') |
123 rqlst = parse('Any S WHERE S documented_by C, C eid %(u)s') |
124 rewrite(rqlst, {('C', 'X'): (card_constraint,), ('S', 'X'): affaire_constraints}, |
124 rewrite(rqlst, {('C', 'X'): (card_constraint,), ('S', 'X'): affaire_constraints}, |
125 kwargs) |
125 kwargs) |
126 self.assertMultiLineEqual(rqlst.as_string(), |
126 self.assertMultiLineEqual( |
127 "Any S WHERE S documented_by C, C eid %(u)s, B eid %(D)s, " |
127 rqlst.as_string(), |
128 "EXISTS(C in_state A, B in_group E, F require_state A, " |
128 "Any S WHERE S documented_by C, C eid %(u)s, B eid %(D)s, " |
129 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), " |
129 "EXISTS(C in_state A, B in_group E, F require_state A, " |
130 "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), " |
130 "F name 'read', F require_group E, A is State, E is CWGroup, F is CWPermission), " |
131 "S is Affaire") |
131 "(EXISTS(S ref LIKE 'PUBLIC%')) OR (EXISTS(B in_group G, G name 'public', G is CWGroup)), " |
132 self.failUnless('D' in kwargs) |
132 "S is Affaire") |
|
133 self.assertTrue('D' in kwargs) |
133 |
134 |
134 def test_or(self): |
135 def test_or(self): |
135 constraint = '(X identity U) OR (X in_state ST, CL identity U, CL in_state ST, ST name "subscribed")' |
136 constraint = '(X identity U) OR (X in_state ST, CL identity U, CL in_state ST, ST name "subscribed")' |
136 rqlst = parse('Any S WHERE S owned_by C, C eid %(u)s, S is in (CWUser, CWGroup)') |
137 rqlst = parse('Any S WHERE S owned_by C, C eid %(u)s, S is in (CWUser, CWGroup)') |
137 rewrite(rqlst, {('C', 'X'): (constraint,)}, {'u':1}) |
138 rewrite(rqlst, {('C', 'X'): (constraint,)}, {'u':1}) |
138 self.failUnlessEqual(rqlst.as_string(), |
139 self.assertEqual(rqlst.as_string(), |
139 "Any S WHERE S owned_by C, C eid %(u)s, S is IN(CWUser, CWGroup), A eid %(B)s, " |
140 "Any S WHERE S owned_by C, C eid %(u)s, S is IN(CWUser, CWGroup), A eid %(B)s, " |
140 "EXISTS((C identity A) OR (C in_state D, E identity A, " |
141 "EXISTS((C identity A) OR (C in_state D, E identity A, " |
141 "E in_state D, D name 'subscribed'), D is State, E is CWUser)") |
142 "E in_state D, D name 'subscribed'), D is State, E is CWUser)") |
142 |
143 |
143 def test_simplified_rqlst(self): |
144 def test_simplified_rqlst(self): |
144 constraint = ('X in_state S, U in_group G, P require_state S,' |
145 constraint = ('X in_state S, U in_group G, P require_state S,' |
145 'P name "read", P require_group G') |
146 'P name "read", P require_group G') |
146 rqlst = parse('Any 2') # this is the simplified rql st for Any X WHERE X eid 12 |
147 rqlst = parse('Any 2') # this is the simplified rql st for Any X WHERE X eid 12 |
147 rewrite(rqlst, {('2', 'X'): (constraint,)}, {}) |
148 rewrite(rqlst, {('2', 'X'): (constraint,)}, {}) |
148 self.failUnlessEqual(rqlst.as_string(), |
149 self.assertEqual(rqlst.as_string(), |
149 u"Any 2 WHERE B eid %(C)s, " |
150 u"Any 2 WHERE B eid %(C)s, " |
150 "EXISTS(2 in_state A, B in_group D, E require_state A, " |
151 "EXISTS(2 in_state A, B in_group D, E require_state A, " |
151 "E name 'read', E require_group D, A is State, D is CWGroup, E is CWPermission)") |
152 "E name 'read', E require_group D, A is State, D is CWGroup, E is CWPermission)") |
152 |
153 |
153 def test_optional_var_1(self): |
154 def test_optional_var_1(self): |
154 constraint = ('X in_state S, U in_group G, P require_state S,' |
155 constraint = ('X in_state S, U in_group G, P require_state S,' |
155 'P name "read", P require_group G') |
156 'P name "read", P require_group G') |
156 rqlst = parse('Any A,C WHERE A documented_by C?') |
157 rqlst = parse('Any A,C WHERE A documented_by C?') |
157 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}) |
158 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}) |
158 self.failUnlessEqual(rqlst.as_string(), |
159 self.assertEqual(rqlst.as_string(), |
159 "Any A,C WHERE A documented_by C?, A is Affaire " |
160 "Any A,C WHERE A documented_by C?, A is Affaire " |
160 "WITH C BEING " |
161 "WITH C BEING " |
161 "(Any C WHERE EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', " |
162 "(Any C WHERE EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', " |
162 "G require_group F), D eid %(A)s, C is Card)") |
163 "G require_group F), D eid %(A)s, C is Card)") |
163 |
164 |
164 def test_optional_var_2(self): |
165 def test_optional_var_2(self): |
165 constraint = ('X in_state S, U in_group G, P require_state S,' |
166 constraint = ('X in_state S, U in_group G, P require_state S,' |
166 'P name "read", P require_group G') |
167 'P name "read", P require_group G') |
167 rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T') |
168 rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T') |
168 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}) |
169 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}) |
169 self.failUnlessEqual(rqlst.as_string(), |
170 self.assertEqual(rqlst.as_string(), |
170 "Any A,C,T WHERE A documented_by C?, A is Affaire " |
171 "Any A,C,T WHERE A documented_by C?, A is Affaire " |
171 "WITH C,T BEING " |
172 "WITH C,T BEING " |
172 "(Any C,T WHERE C title T, EXISTS(C in_state B, D in_group F, " |
173 "(Any C,T WHERE C title T, EXISTS(C in_state B, D in_group F, " |
173 "G require_state B, G name 'read', G require_group F), " |
174 "G require_state B, G name 'read', G require_group F), " |
174 "D eid %(A)s, C is Card)") |
175 "D eid %(A)s, C is Card)") |
175 |
176 |
176 def test_optional_var_3(self): |
177 def test_optional_var_3(self): |
177 constraint1 = ('X in_state S, U in_group G, P require_state S,' |
178 constraint1 = ('X in_state S, U in_group G, P require_state S,' |
178 'P name "read", P require_group G') |
179 'P name "read", P require_group G') |
179 constraint2 = 'X in_state S, S name "public"' |
180 constraint2 = 'X in_state S, S name "public"' |
180 rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T') |
181 rqlst = parse('Any A,C,T WHERE A documented_by C?, C title T') |
181 rewrite(rqlst, {('C', 'X'): (constraint1, constraint2)}, {}) |
182 rewrite(rqlst, {('C', 'X'): (constraint1, constraint2)}, {}) |
182 self.failUnlessEqual(rqlst.as_string(), |
183 self.assertEqual(rqlst.as_string(), |
183 "Any A,C,T WHERE A documented_by C?, A is Affaire " |
184 "Any A,C,T WHERE A documented_by C?, A is Affaire " |
184 "WITH C,T BEING (Any C,T WHERE C title T, " |
185 "WITH C,T BEING (Any C,T WHERE C title T, " |
185 "EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', G require_group F), " |
186 "(EXISTS(C in_state B, D in_group F, G require_state B, G name 'read', G require_group F)) " |
186 "D eid %(A)s, C is Card, " |
187 "OR (EXISTS(C in_state E, E name 'public')), " |
187 "EXISTS(C in_state E, E name 'public'))") |
188 "D eid %(A)s, C is Card)") |
188 |
189 |
189 def test_optional_var_4(self): |
190 def test_optional_var_4(self): |
190 constraint1 = 'A created_by U, X documented_by A' |
191 constraint1 = 'A created_by U, X documented_by A' |
191 constraint2 = 'A created_by U, X concerne A' |
192 constraint2 = 'A created_by U, X concerne A' |
192 constraint3 = 'X created_by U' |
193 constraint3 = 'X created_by U' |
193 rqlst = parse('Any X,LA,Y WHERE LA? documented_by X, LA concerne Y') |
194 rqlst = parse('Any X,LA,Y WHERE LA? documented_by X, LA concerne Y') |
194 rewrite(rqlst, {('LA', 'X'): (constraint1, constraint2), |
195 rewrite(rqlst, {('LA', 'X'): (constraint1, constraint2), |
195 ('X', 'X'): (constraint3,), |
196 ('X', 'X'): (constraint3,), |
196 ('Y', 'X'): (constraint3,)}, {}) |
197 ('Y', 'X'): (constraint3,)}, {}) |
197 self.failUnlessEqual(rqlst.as_string(), |
198 self.assertEqual(rqlst.as_string(), |
198 u'Any X,LA,Y WHERE LA? documented_by X, LA concerne Y, B eid %(C)s, ' |
199 u'Any X,LA,Y WHERE LA? documented_by X, LA concerne Y, B eid %(C)s, ' |
199 'EXISTS(X created_by B), EXISTS(Y created_by B), ' |
200 'EXISTS(X created_by B), EXISTS(Y created_by B), ' |
200 'X is Card, Y is IN(Division, Note, Societe) ' |
201 'X is Card, Y is IN(Division, Note, Societe) ' |
201 'WITH LA BEING (Any LA WHERE EXISTS(A created_by B, LA documented_by A), ' |
202 'WITH LA BEING (Any LA WHERE (EXISTS(A created_by B, LA documented_by A)) OR (EXISTS(E created_by B, LA concerne E)), ' |
202 'B eid %(D)s, LA is Affaire, EXISTS(E created_by B, LA concerne E))') |
203 'B eid %(D)s, LA is Affaire)') |
203 |
204 |
204 def test_optional_var_inlined(self): |
205 def test_optional_var_inlined(self): |
205 c1 = ('X require_permission P') |
206 c1 = ('X require_permission P') |
206 c2 = ('X inlined_card O, O require_permission P') |
207 c2 = ('X inlined_card O, O require_permission P') |
207 rqlst = parse('Any C,A,R WHERE A? inlined_card C, A ref R') |
208 rqlst = parse('Any C,A,R WHERE A? inlined_card C, A ref R') |
208 rewrite(rqlst, {('C', 'X'): (c1,), |
209 rewrite(rqlst, {('C', 'X'): (c1,), |
209 ('A', 'X'): (c2,), |
210 ('A', 'X'): (c2,), |
210 }, {}) |
211 }, {}) |
211 # XXX suboptimal |
212 # XXX suboptimal |
212 self.failUnlessEqual(rqlst.as_string(), |
213 self.assertEqual(rqlst.as_string(), |
213 "Any C,A,R WITH A,C,R BEING " |
214 "Any C,A,R WITH A,C,R BEING " |
214 "(Any A,C,R WHERE A? inlined_card C, A ref R, " |
215 "(Any A,C,R WHERE A? inlined_card C, A ref R, " |
215 "(A is NULL) OR (EXISTS(A inlined_card B, B require_permission D, " |
216 "(A is NULL) OR (EXISTS(A inlined_card B, B require_permission D, " |
216 "B is Card, D is CWPermission)), " |
217 "B is Card, D is CWPermission)), " |
217 "A is Affaire, C is Card, EXISTS(C require_permission E, E is CWPermission))") |
218 "A is Affaire, C is Card, EXISTS(C require_permission E, E is CWPermission))") |
218 |
219 |
219 # def test_optional_var_inlined_has_perm(self): |
220 # def test_optional_var_inlined_has_perm(self): |
220 # c1 = ('X require_permission P') |
221 # c1 = ('X require_permission P') |
221 # c2 = ('X inlined_card O, U has_read_permission O') |
222 # c2 = ('X inlined_card O, U has_read_permission O') |
222 # rqlst = parse('Any C,A,R WHERE A? inlined_card C, A ref R') |
223 # rqlst = parse('Any C,A,R WHERE A? inlined_card C, A ref R') |
223 # rewrite(rqlst, {('C', 'X'): (c1,), |
224 # rewrite(rqlst, {('C', 'X'): (c1,), |
224 # ('A', 'X'): (c2,), |
225 # ('A', 'X'): (c2,), |
225 # }, {}) |
226 # }, {}) |
226 # self.failUnlessEqual(rqlst.as_string(), |
227 # self.assertEqual(rqlst.as_string(), |
227 # "") |
228 # "") |
228 |
229 |
229 def test_optional_var_inlined_imbricated_error(self): |
230 def test_optional_var_inlined_imbricated_error(self): |
230 c1 = ('X require_permission P') |
231 c1 = ('X require_permission P') |
231 c2 = ('X inlined_card O, O require_permission P') |
232 c2 = ('X inlined_card O, O require_permission P') |
240 c1 = ('X require_permission P') |
241 c1 = ('X require_permission P') |
241 c2 = ('X inlined_card O, O require_permission P') |
242 c2 = ('X inlined_card O, O require_permission P') |
242 rqlst = parse('Any A,W WHERE A inlined_card C?, C inlined_note N, ' |
243 rqlst = parse('Any A,W WHERE A inlined_card C?, C inlined_note N, ' |
243 'N inlined_affaire W') |
244 'N inlined_affaire W') |
244 rewrite(rqlst, {('C', 'X'): (c1,)}, {}) |
245 rewrite(rqlst, {('C', 'X'): (c1,)}, {}) |
245 self.failUnlessEqual(rqlst.as_string(), |
246 self.assertEqual(rqlst.as_string(), |
246 'Any A,W WHERE A inlined_card C?, A is Affaire ' |
247 'Any A,W WHERE A inlined_card C?, A is Affaire ' |
247 'WITH C,N,W BEING (Any C,N,W WHERE C inlined_note N, ' |
248 'WITH C,N,W BEING (Any C,N,W WHERE C inlined_note N, ' |
248 'N inlined_affaire W, EXISTS(C require_permission B), ' |
249 'N inlined_affaire W, EXISTS(C require_permission B), ' |
249 'C is Card, N is Note, W is Affaire)') |
250 'C is Card, N is Note, W is Affaire)') |
250 |
251 |
251 def test_relation_optimization_1_lhs(self): |
252 def test_relation_optimization_1_lhs(self): |
252 # since Card in_state State as monovalued cardinality, the in_state |
253 # since Card in_state State as monovalued cardinality, the in_state |
253 # relation used in the rql expression can be ignored and S replaced by |
254 # relation used in the rql expression can be ignored and S replaced by |
254 # the variable from the incoming query |
255 # the variable from the incoming query |
255 snippet = ('X in_state S, S name "hop"') |
256 snippet = ('X in_state S, S name "hop"') |
256 rqlst = parse('Card C WHERE C in_state STATE') |
257 rqlst = parse('Card C WHERE C in_state STATE') |
257 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
258 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
258 self.failUnlessEqual(rqlst.as_string(), |
259 self.assertEqual(rqlst.as_string(), |
259 "Any C WHERE C in_state STATE, C is Card, " |
260 "Any C WHERE C in_state STATE, C is Card, " |
260 "EXISTS(STATE name 'hop'), STATE is State") |
261 "EXISTS(STATE name 'hop'), STATE is State") |
261 |
262 |
262 def test_relation_optimization_1_rhs(self): |
263 def test_relation_optimization_1_rhs(self): |
263 snippet = ('TW subworkflow_exit X, TW name "hop"') |
264 snippet = ('TW subworkflow_exit X, TW name "hop"') |
264 rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT') |
265 rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT') |
265 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
266 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
266 self.failUnlessEqual(rqlst.as_string(), |
267 self.assertEqual(rqlst.as_string(), |
267 "Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, " |
268 "Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, " |
268 "EXISTS(C name 'hop'), EXIT is SubWorkflowExitPoint") |
269 "EXISTS(C name 'hop'), EXIT is SubWorkflowExitPoint") |
269 |
270 |
270 def test_relation_optimization_2_lhs(self): |
271 def test_relation_optimization_2_lhs(self): |
271 # optional relation can be shared if also optional in the snippet |
272 # optional relation can be shared if also optional in the snippet |
272 snippet = ('X in_state S?, S name "hop"') |
273 snippet = ('X in_state S?, S name "hop"') |
273 rqlst = parse('Card C WHERE C in_state STATE?') |
274 rqlst = parse('Card C WHERE C in_state STATE?') |
274 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
275 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
275 self.failUnlessEqual(rqlst.as_string(), |
276 self.assertEqual(rqlst.as_string(), |
276 "Any C WHERE C in_state STATE?, C is Card, " |
277 "Any C WHERE C in_state STATE?, C is Card, " |
277 "EXISTS(STATE name 'hop'), STATE is State") |
278 "EXISTS(STATE name 'hop'), STATE is State") |
278 def test_relation_optimization_2_rhs(self): |
279 def test_relation_optimization_2_rhs(self): |
279 snippet = ('TW? subworkflow_exit X, TW name "hop"') |
280 snippet = ('TW? subworkflow_exit X, TW name "hop"') |
280 rqlst = parse('SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT') |
281 rqlst = parse('SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT') |
281 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
282 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
282 self.failUnlessEqual(rqlst.as_string(), |
283 self.assertEqual(rqlst.as_string(), |
283 "Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, " |
284 "Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, " |
284 "EXISTS(C name 'hop'), C is WorkflowTransition") |
285 "EXISTS(C name 'hop'), C is WorkflowTransition") |
285 |
286 |
286 def test_relation_optimization_3_lhs(self): |
287 def test_relation_optimization_3_lhs(self): |
287 # optional relation in the snippet but not in the orig tree can be shared |
288 # optional relation in the snippet but not in the orig tree can be shared |
288 snippet = ('X in_state S?, S name "hop"') |
289 snippet = ('X in_state S?, S name "hop"') |
289 rqlst = parse('Card C WHERE C in_state STATE') |
290 rqlst = parse('Card C WHERE C in_state STATE') |
290 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
291 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
291 self.failUnlessEqual(rqlst.as_string(), |
292 self.assertEqual(rqlst.as_string(), |
292 "Any C WHERE C in_state STATE, C is Card, " |
293 "Any C WHERE C in_state STATE, C is Card, " |
293 "EXISTS(STATE name 'hop'), STATE is State") |
294 "EXISTS(STATE name 'hop'), STATE is State") |
294 def test_relation_optimization_3_rhs(self): |
295 def test_relation_optimization_3_rhs(self): |
295 snippet = ('TW? subworkflow_exit X, TW name "hop"') |
296 snippet = ('TW? subworkflow_exit X, TW name "hop"') |
296 rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT') |
297 rqlst = parse('WorkflowTransition C WHERE C subworkflow_exit EXIT') |
297 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
298 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
298 self.failUnlessEqual(rqlst.as_string(), |
299 self.assertEqual(rqlst.as_string(), |
299 "Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, " |
300 "Any C WHERE C subworkflow_exit EXIT, C is WorkflowTransition, " |
300 "EXISTS(C name 'hop'), EXIT is SubWorkflowExitPoint") |
301 "EXISTS(C name 'hop'), EXIT is SubWorkflowExitPoint") |
301 |
302 |
302 def test_relation_non_optimization_1_lhs(self): |
303 def test_relation_non_optimization_1_lhs(self): |
303 # but optional relation in the orig tree but not in the snippet can't be shared |
304 # but optional relation in the orig tree but not in the snippet can't be shared |
304 snippet = ('X in_state S, S name "hop"') |
305 snippet = ('X in_state S, S name "hop"') |
305 rqlst = parse('Card C WHERE C in_state STATE?') |
306 rqlst = parse('Card C WHERE C in_state STATE?') |
306 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
307 rewrite(rqlst, {('C', 'X'): (snippet,)}, {}) |
307 self.failUnlessEqual(rqlst.as_string(), |
308 self.assertEqual(rqlst.as_string(), |
308 "Any C WHERE C in_state STATE?, C is Card, " |
309 "Any C WHERE C in_state STATE?, C is Card, " |
309 "EXISTS(C in_state A, A name 'hop', A is State), STATE is State") |
310 "EXISTS(C in_state A, A name 'hop', A is State), STATE is State") |
310 def test_relation_non_optimization_1_rhs(self): |
311 def test_relation_non_optimization_1_rhs(self): |
311 snippet = ('TW subworkflow_exit X, TW name "hop"') |
312 snippet = ('TW subworkflow_exit X, TW name "hop"') |
312 rqlst = parse('SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT') |
313 rqlst = parse('SubWorkflowExitPoint EXIT WHERE C? subworkflow_exit EXIT') |
313 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
314 rewrite(rqlst, {('EXIT', 'X'): (snippet,)}, {}) |
314 self.failUnlessEqual(rqlst.as_string(), |
315 self.assertEqual(rqlst.as_string(), |
315 "Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, " |
316 "Any EXIT WHERE C? subworkflow_exit EXIT, EXIT is SubWorkflowExitPoint, " |
316 "EXISTS(A subworkflow_exit EXIT, A name 'hop', A is WorkflowTransition), " |
317 "EXISTS(A subworkflow_exit EXIT, A name 'hop', A is WorkflowTransition), " |
317 "C is WorkflowTransition") |
318 "C is WorkflowTransition") |
318 |
319 |
319 def test_unsupported_constraint_1(self): |
320 def test_unsupported_constraint_1(self): |
320 # CWUser doesn't have require_permission |
321 # CWUser doesn't have require_permission |
321 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
322 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
322 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
323 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
324 |
325 |
325 def test_unsupported_constraint_2(self): |
326 def test_unsupported_constraint_2(self): |
326 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
327 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
327 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
328 rqlst = parse('Any U,T WHERE U is CWUser, T wf_info_for U') |
328 rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X wf_info_for Y, Y in_group G, G name "managers"')}, {}) |
329 rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X wf_info_for Y, Y in_group G, G name "managers"')}, {}) |
329 self.failUnlessEqual(rqlst.as_string(), |
330 self.assertEqual(rqlst.as_string(), |
330 u"Any U,T WHERE U is CWUser, T wf_info_for U, " |
331 u"Any U,T WHERE U is CWUser, T wf_info_for U, " |
331 "EXISTS(U in_group B, B name 'managers', B is CWGroup), T is TrInfo") |
332 "EXISTS(U in_group B, B name 'managers', B is CWGroup), T is TrInfo") |
332 |
333 |
333 def test_unsupported_constraint_3(self): |
334 def test_unsupported_constraint_3(self): |
334 self.skipTest('raise unauthorized for now') |
335 self.skipTest('raise unauthorized for now') |
335 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
336 trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"') |
336 rqlst = parse('Any T WHERE T wf_info_for X') |
337 rqlst = parse('Any T WHERE T wf_info_for X') |
337 rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X in_group G, G name "managers"')}, {}) |
338 rewrite(rqlst, {('T', 'X'): (trinfo_constraint, 'X in_group G, G name "managers"')}, {}) |
338 self.failUnlessEqual(rqlst.as_string(), |
339 self.assertEqual(rqlst.as_string(), |
339 u'XXX dunno what should be generated') |
340 u'XXX dunno what should be generated') |
340 |
341 |
341 def test_add_ambiguity_exists(self): |
342 def test_add_ambiguity_exists(self): |
342 constraint = ('X concerne Y') |
343 constraint = ('X concerne Y') |
343 rqlst = parse('Affaire X') |
344 rqlst = parse('Affaire X') |
344 rewrite(rqlst, {('X', 'X'): (constraint,)}, {}) |
345 rewrite(rqlst, {('X', 'X'): (constraint,)}, {}) |
345 self.failUnlessEqual(rqlst.as_string(), |
346 self.assertEqual(rqlst.as_string(), |
346 u"Any X WHERE X is Affaire, ((EXISTS(X concerne A, A is Division)) OR (EXISTS(X concerne C, C is Societe))) OR (EXISTS(X concerne B, B is Note))") |
347 u"Any X WHERE X is Affaire, ((EXISTS(X concerne A, A is Division)) OR (EXISTS(X concerne C, C is Societe))) OR (EXISTS(X concerne B, B is Note))") |
347 |
348 |
348 def test_add_ambiguity_outerjoin(self): |
349 def test_add_ambiguity_outerjoin(self): |
349 constraint = ('X concerne Y') |
350 constraint = ('X concerne Y') |
350 rqlst = parse('Any X,C WHERE X? documented_by C') |
351 rqlst = parse('Any X,C WHERE X? documented_by C') |
351 rewrite(rqlst, {('X', 'X'): (constraint,)}, {}) |
352 rewrite(rqlst, {('X', 'X'): (constraint,)}, {}) |
352 # ambiguity are kept in the sub-query, no need to be resolved using OR |
353 # ambiguity are kept in the sub-query, no need to be resolved using OR |
353 self.failUnlessEqual(rqlst.as_string(), |
354 self.assertEqual(rqlst.as_string(), |
354 u"Any X,C WHERE X? documented_by C, C is Card WITH X BEING (Any X WHERE EXISTS(X concerne A), X is Affaire)") |
355 u"Any X,C WHERE X? documented_by C, C is Card WITH X BEING (Any X WHERE EXISTS(X concerne A), X is Affaire)") |
355 |
356 |
356 |
357 |
357 def test_rrqlexpr_nonexistant_subject_1(self): |
358 def test_rrqlexpr_nonexistant_subject_1(self): |
358 constraint = RRQLExpression('S owned_by U') |
359 constraint = RRQLExpression('S owned_by U') |
359 rqlst = parse('Card C') |
360 rqlst = parse('Card C') |
360 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
361 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
361 self.failUnlessEqual(rqlst.as_string(), |
362 self.assertEqual(rqlst.as_string(), |
362 u"Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)") |
363 u"Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)") |
363 rqlst = parse('Card C') |
364 rqlst = parse('Card C') |
364 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU') |
365 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU') |
365 self.failUnlessEqual(rqlst.as_string(), |
366 self.assertEqual(rqlst.as_string(), |
366 u"Any C WHERE C is Card") |
367 u"Any C WHERE C is Card") |
367 rqlst = parse('Card C') |
368 rqlst = parse('Card C') |
368 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SOU') |
369 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SOU') |
369 self.failUnlessEqual(rqlst.as_string(), |
370 self.assertEqual(rqlst.as_string(), |
370 u"Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)") |
371 u"Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)") |
371 |
372 |
372 def test_rrqlexpr_nonexistant_subject_2(self): |
373 def test_rrqlexpr_nonexistant_subject_2(self): |
373 constraint = RRQLExpression('S owned_by U, O owned_by U, O is Card') |
374 constraint = RRQLExpression('S owned_by U, O owned_by U, O is Card') |
374 rqlst = parse('Card C') |
375 rqlst = parse('Card C') |
375 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
376 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
376 self.failUnlessEqual(rqlst.as_string(), |
377 self.assertEqual(rqlst.as_string(), |
377 'Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)') |
378 'Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A)') |
378 rqlst = parse('Card C') |
379 rqlst = parse('Card C') |
379 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU') |
380 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU') |
380 self.failUnlessEqual(rqlst.as_string(), |
381 self.assertEqual(rqlst.as_string(), |
381 'Any C WHERE C is Card, B eid %(D)s, EXISTS(A owned_by B, A is Card)') |
382 'Any C WHERE C is Card, B eid %(D)s, EXISTS(A owned_by B, A is Card)') |
382 rqlst = parse('Card C') |
383 rqlst = parse('Card C') |
383 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SOU') |
384 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SOU') |
384 self.failUnlessEqual(rqlst.as_string(), |
385 self.assertEqual(rqlst.as_string(), |
385 'Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A, D owned_by A, D is Card)') |
386 'Any C WHERE C is Card, A eid %(B)s, EXISTS(C owned_by A, D owned_by A, D is Card)') |
386 |
387 |
387 def test_rrqlexpr_nonexistant_subject_3(self): |
388 def test_rrqlexpr_nonexistant_subject_3(self): |
388 constraint = RRQLExpression('U in_group G, G name "users"') |
389 constraint = RRQLExpression('U in_group G, G name "users"') |
389 rqlst = parse('Card C') |
390 rqlst = parse('Card C') |
390 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
391 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
391 self.failUnlessEqual(rqlst.as_string(), |
392 self.assertEqual(rqlst.as_string(), |
392 u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", D is CWGroup)') |
393 u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", D is CWGroup)') |
393 |
394 |
394 def test_rrqlexpr_nonexistant_subject_4(self): |
395 def test_rrqlexpr_nonexistant_subject_4(self): |
395 constraint = RRQLExpression('U in_group G, G name "users", S owned_by U') |
396 constraint = RRQLExpression('U in_group G, G name "users", S owned_by U') |
396 rqlst = parse('Card C') |
397 rqlst = parse('Card C') |
397 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
398 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'SU') |
398 self.failUnlessEqual(rqlst.as_string(), |
399 self.assertEqual(rqlst.as_string(), |
399 u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", C owned_by A, D is CWGroup)') |
400 u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", C owned_by A, D is CWGroup)') |
400 rqlst = parse('Card C') |
401 rqlst = parse('Card C') |
401 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU') |
402 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'OU') |
402 self.failUnlessEqual(rqlst.as_string(), |
403 self.assertEqual(rqlst.as_string(), |
403 u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", D is CWGroup)') |
404 u'Any C WHERE C is Card, A eid %(B)s, EXISTS(A in_group D, D name "users", D is CWGroup)') |
404 |
405 |
405 def test_rrqlexpr_nonexistant_subject_5(self): |
406 def test_rrqlexpr_nonexistant_subject_5(self): |
406 constraint = RRQLExpression('S owned_by Z, O owned_by Z, O is Card') |
407 constraint = RRQLExpression('S owned_by Z, O owned_by Z, O is Card') |
407 rqlst = parse('Card C') |
408 rqlst = parse('Card C') |
408 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'S') |
409 rewrite(rqlst, {('C', 'S'): (constraint,)}, {}, 'S') |
409 self.failUnlessEqual(rqlst.as_string(), |
410 self.assertEqual(rqlst.as_string(), |
410 u"Any C WHERE C is Card, EXISTS(C owned_by A, A is CWUser)") |
411 u"Any C WHERE C is Card, EXISTS(C owned_by A, A is CWUser)") |
411 |
412 |
412 def test_rqlexpr_not_relation_1_1(self): |
413 def test_rqlexpr_not_relation_1_1(self): |
413 constraint = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
414 constraint = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
414 rqlst = parse('Affaire A WHERE NOT EXISTS(A documented_by C)') |
415 rqlst = parse('Affaire A WHERE NOT EXISTS(A documented_by C)') |
415 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}, 'X') |
416 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}, 'X') |
416 self.failUnlessEqual(rqlst.as_string(), |
417 self.assertEqual(rqlst.as_string(), |
417 u'Any A WHERE NOT EXISTS(A documented_by C, EXISTS(C owned_by B, B login "hop", B is CWUser), C is Card), A is Affaire') |
418 u'Any A WHERE NOT EXISTS(A documented_by C, EXISTS(C owned_by B, B login "hop", B is CWUser), C is Card), A is Affaire') |
418 |
419 |
419 def test_rqlexpr_not_relation_1_2(self): |
420 def test_rqlexpr_not_relation_1_2(self): |
420 constraint = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
421 constraint = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
421 rqlst = parse('Affaire A WHERE NOT EXISTS(A documented_by C)') |
422 rqlst = parse('Affaire A WHERE NOT EXISTS(A documented_by C)') |
422 rewrite(rqlst, {('A', 'X'): (constraint,)}, {}, 'X') |
423 rewrite(rqlst, {('A', 'X'): (constraint,)}, {}, 'X') |
423 self.failUnlessEqual(rqlst.as_string(), |
424 self.assertEqual(rqlst.as_string(), |
424 u'Any A WHERE NOT EXISTS(A documented_by C, C is Card), A is Affaire, EXISTS(A owned_by B, B login "hop", B is CWUser)') |
425 u'Any A WHERE NOT EXISTS(A documented_by C, C is Card), A is Affaire, EXISTS(A owned_by B, B login "hop", B is CWUser)') |
425 |
426 |
426 def test_rqlexpr_not_relation_2(self): |
427 def test_rqlexpr_not_relation_2(self): |
427 constraint = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
428 constraint = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
428 rqlst = rqlhelper.parse('Affaire A WHERE NOT A documented_by C', annotate=False) |
429 rqlst = rqlhelper.parse('Affaire A WHERE NOT A documented_by C', annotate=False) |
429 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}, 'X') |
430 rewrite(rqlst, {('C', 'X'): (constraint,)}, {}, 'X') |
430 self.failUnlessEqual(rqlst.as_string(), |
431 self.assertEqual(rqlst.as_string(), |
431 u'Any A WHERE NOT EXISTS(A documented_by C, EXISTS(C owned_by B, B login "hop", B is CWUser), C is Card), A is Affaire') |
432 u'Any A WHERE NOT EXISTS(A documented_by C, EXISTS(C owned_by B, B login "hop", B is CWUser), C is Card), A is Affaire') |
432 |
433 |
|
434 def test_rqlexpr_multiexpr_outerjoin(self): |
|
435 c1 = RRQLExpression('X owned_by Z, Z login "hop"', 'X') |
|
436 c2 = RRQLExpression('X owned_by Z, Z login "hip"', 'X') |
|
437 c3 = RRQLExpression('X owned_by Z, Z login "momo"', 'X') |
|
438 rqlst = rqlhelper.parse('Any A WHERE A documented_by C?', annotate=False) |
|
439 rewrite(rqlst, {('C', 'X'): (c1, c2, c3)}, {}, 'X') |
|
440 self.assertEqual(rqlst.as_string(), |
|
441 u'Any A WHERE A documented_by C?, A is Affaire ' |
|
442 'WITH C BEING (Any C WHERE ((EXISTS(C owned_by B, B login "hop")) ' |
|
443 'OR (EXISTS(C owned_by D, D login "momo"))) ' |
|
444 'OR (EXISTS(C owned_by A, A login "hip")), C is Card)') |
|
445 |
|
446 def test_multiple_erql_one_bad(self): |
|
447 #: reproduce bug #2236985 |
|
448 #: (rqlrewrite fails to remove rewritten entry for unsupported constraint and then crash) |
|
449 #: |
|
450 #: This check a very rare code path triggered by the four condition below |
|
451 |
|
452 # 1. c_ok introduce an ambiguity |
|
453 c_ok = ERQLExpression('X concerne R') |
|
454 # 2. c_bad is just plain wrong and won't be kept |
|
455 # 3. but it declare a new variable |
|
456 # 4. this variable require a rewrite |
|
457 c_bad = ERQLExpression('X documented_by R, A in_state R') |
|
458 |
|
459 rqlst = parse('Any A, R WHERE A ref R, S is Affaire') |
|
460 rewrite(rqlst, {('A', 'X'): (c_ok, c_bad)}, {}) |
433 |
461 |
434 if __name__ == '__main__': |
462 if __name__ == '__main__': |
435 unittest_main() |
463 unittest_main() |