--- a/rqlrewrite.py Thu Nov 12 12:08:43 2009 +0100
+++ b/rqlrewrite.py Thu Nov 12 12:15:19 2009 +0100
@@ -13,6 +13,7 @@
from rql import nodes as n, stmts, TypeResolverException
from logilab.common.compat import any
+from logilab.common.graph import has_path
from cubicweb import Unauthorized, typed_eid
@@ -134,7 +135,7 @@
if len(self.select.solutions) < len(self.solutions):
raise Unsupported()
- def rewrite(self, select, snippets, solutions, kwargs):
+ def rewrite(self, select, snippets, solutions, kwargs, existingvars=None):
"""
snippets: (varmap, list of rql expression)
with varmap a *tuple* (select var, snippet var)
@@ -146,6 +147,7 @@
self.removing_ambiguity = False
self.exists_snippet = {}
self.pending_keys = []
+ self.existingvars = existingvars
# we have to annotate the rqlst before inserting snippets, even though
# we'll have to redo it latter
self.annotate(select)
@@ -213,6 +215,14 @@
def insert_snippet(self, varmap, snippetrqlst, parent=None):
new = snippetrqlst.where.accept(self)
+ existing = self.existingvars
+ self.existingvars = None
+ try:
+ return self._insert_snippet(varmap, parent, new)
+ finally:
+ self.existingvars = existing
+
+ def _insert_snippet(self, varmap, parent, new):
if new is not None:
if self.varinfo.get('stinfo', {}).get('optrelations'):
assert parent is None
@@ -478,8 +488,26 @@
def visit_exists(self, node):
return self._visit_unary(node, n.Exists)
+ def keep_var(self, varname):
+ if varname in 'SO':
+ return varname in self.existingvars
+ if varname == 'U':
+ return True
+ vargraph = self.current_expr.vargraph
+ for existingvar in self.existingvars:
+ #path = has_path(vargraph, varname, existingvar)
+ if has_path(vargraph, varname, existingvar):
+ return True
+ # no path from this variable to an existing variable
+ return False
+
def visit_relation(self, node):
lhs, rhs = node.get_variable_parts()
+ # remove relations where an unexistant variable and or a variable linked
+ # to an unexistant variable is used.
+ if self.existingvars:
+ if not self.keep_var(lhs.name):
+ return
if node.r_type in ('has_add_permission', 'has_update_permission',
'has_delete_permission', 'has_read_permission'):
assert lhs.name == 'U'
@@ -488,6 +516,8 @@
self.pending_keys.append( (key, action) )
return
if isinstance(rhs, n.VariableRef):
+ if self.existingvars and not self.keep_var(rhs.name):
+ return
if lhs.name in self.revvarmap and rhs.name != 'U':
orel = self._may_be_shared_with(node, 'object', lhs.name)
if orel is not None: