--- a/server/msplanner.py Fri Mar 20 09:15:14 2009 +0100
+++ b/server/msplanner.py Fri Mar 20 12:51:39 2009 +0100
@@ -149,7 +149,15 @@
select.append_selected(vref.copy(select))
if select.groupby and not vref in select.groupby:
select.add_group_var(vref.copy(select))
-
+
+# XXX move to rql
+def is_ancestor(n1, n2):
+ p = n1.parent
+ while p is not None:
+ if p is n2:
+ return True
+ p = p.parent
+ return False
class PartPlanInformation(object):
"""regroups necessary information to execute some part of a "global" rql
@@ -194,7 +202,7 @@
self._inputmaps = {}
if rqlhelper is not None: # else test
self._insert_identity_variable = rqlhelper._annotator.rewrite_shared_optional
-
+
def copy_solutions(self, solindices):
return [self._solutions[solidx].copy() for solidx in solindices]
@@ -431,8 +439,14 @@
# can't get information from relation inside a NOT exists
# where variables don't belong to the same scope
continue
- if not (var.scope is rel.scope and ovar.scope is rel.scope) and rel.ored():
- continue
+ need_ancestor_scope = False
+ if not (var.scope is rel.scope and ovar.scope is rel.scope):
+ if rel.ored():
+ continue
+ if rel.ored(traverse_scope=True):
+ # if relation has some OR as parent, constraints should only
+ # propagate from parent scope to child scope, nothing else
+ need_ancestor_scope = True
relsources = self._session.repo.rel_type_sources(rel.r_type)
if rel.neged(strict=True) and (
len(relsources) < 2
@@ -448,8 +462,10 @@
continue
norelsup = self._norel_support_set(rel)
# compute invalid sources for variables and remove them
- self._remove_var_sources(var, norelsup, ovar, vsources)
- self._remove_var_sources(ovar, norelsup, var, vsources)
+ if not need_ancestor_scope or is_ancestor(var.scope, ovar.scope):
+ self._remove_var_sources(var, norelsup, ovar, vsources)
+ if not need_ancestor_scope or is_ancestor(ovar.scope, var.scope):
+ self._remove_var_sources(ovar, norelsup, var, vsources)
def _remove_var_sources(self, var, norelsup, ovar, vsources):
"""remove invalid sources for var according to ovar's sources and the
--- a/server/test/unittest_msplanner.py Fri Mar 20 09:15:14 2009 +0100
+++ b/server/test/unittest_msplanner.py Fri Mar 20 12:51:39 2009 +0100
@@ -1818,6 +1818,28 @@
)],
{'x': 999999})
+ def test_nonregr13(self):
+ self._test('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File '
+ 'WITH U,UL BEING (Any U,UL WHERE ME eid %(x)s, (EXISTS(U identity ME) '
+ 'OR (EXISTS(U in_group G, G name IN("managers", "staff")))) '
+ 'OR (EXISTS(U in_group H, ME in_group H, NOT H name "users")), U login UL, U is EUser)',
+ [('FetchStep', [('Any U,UL WHERE U login UL, U is EUser',
+ [{'U': 'EUser', 'UL': 'String'}])],
+ [self.ldap, self.system], None,
+ {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
+ []),
+ ('FetchStep', [('Any U,UL WHERE ((EXISTS(U identity 5)) OR (EXISTS(U in_group G, G name IN("managers", "staff"), G is EGroup))) OR (EXISTS(U in_group H, 5 in_group H, NOT H name "users", H is EGroup)), U login UL, U is EUser',
+ [{'G': 'EGroup', 'H': 'EGroup', 'U': 'EUser', 'UL': 'String'}])],
+ [self.system],
+ {'U': 'table0.C0', 'U.login': 'table0.C1', 'UL': 'table0.C1'},
+ {'U': 'table1.C0', 'U.login': 'table1.C1', 'UL': 'table1.C1'},
+ []),
+ ('OneFetchStep', [('Any B,U,UL GROUPBY B,U,UL WHERE B created_by U?, B is File',
+ [{'B': 'File', 'U': 'EUser', 'UL': 'String'}])],
+ None, None, [self.system],
+ {'U': 'table1.C0', 'UL': 'table1.C1'},
+ [])],
+ {'x': self.session.user.eid})
class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
"""test planner related feature on a 3-sources repository: