equal
deleted
inserted
replaced
202 |
202 |
203 |
203 |
204 def iter_relations(stinfo): |
204 def iter_relations(stinfo): |
205 # this is a function so that test may return relation in a predictable order |
205 # this is a function so that test may return relation in a predictable order |
206 return stinfo['relations'] - stinfo['rhsrelations'] |
206 return stinfo['relations'] - stinfo['rhsrelations'] |
|
207 |
|
208 |
|
209 def need_exists(node): |
|
210 """Return true if the given node should be wrapped in an `Exists` node. |
|
211 |
|
212 This is true when node isn't already an `Exists` or `Not` node, nor a |
|
213 `And`/`Or` of `Exists` or `Not` nodes. |
|
214 """ |
|
215 if isinstance(node, (n.Exists, n.Not)): |
|
216 return False |
|
217 if isinstance(node, (n.Or, n.And)): |
|
218 return need_exists(node.children[0]) or need_exists(node.children[1]) |
|
219 return True |
207 |
220 |
208 |
221 |
209 class Unsupported(Exception): |
222 class Unsupported(Exception): |
210 """raised when an rql expression can't be inserted in some rql query |
223 """raised when an rql expression can't be inserted in some rql query |
211 because it create an unresolvable query (eg no solutions found) |
224 because it create an unresolvable query (eg no solutions found) |
472 return self._insert_snippet(varmap, previous, new) |
485 return self._insert_snippet(varmap, previous, new) |
473 finally: |
486 finally: |
474 self.existingvars = existing |
487 self.existingvars = existing |
475 |
488 |
476 def _inserted_root(self, new): |
489 def _inserted_root(self, new): |
477 if not isinstance(new, (n.Exists, n.Not)): |
490 if need_exists(new): |
478 new = n.Exists(new) |
491 new = n.Exists(new) |
479 return new |
492 return new |
480 |
493 |
481 def _insert_snippet(self, varmap, previous, new): |
494 def _insert_snippet(self, varmap, previous, new): |
482 """insert `new` snippet into the syntax tree, which have been rewritten |
495 """insert `new` snippet into the syntax tree, which have been rewritten |