server/rqlannotation.py
branchstable
changeset 5582 3e133b29a1a4
parent 5426 0d4853a6e5ee
child 6297 23c1e50ff97b
--- a/server/rqlannotation.py	Tue May 25 12:21:17 2010 +0200
+++ b/server/rqlannotation.py	Wed May 26 10:28:48 2010 +0200
@@ -24,7 +24,7 @@
 from logilab.common.compat import any
 
 from rql import BadRQLQuery
-from rql.nodes import Relation, VariableRef, Constant, Variable, Or
+from rql.nodes import Relation, VariableRef, Constant, Variable, Or, Exists
 from rql.utils import common_parent
 
 def _annotate_select(annotator, rqlst):
@@ -36,7 +36,7 @@
     has_text_query = False
     need_distinct = rqlst.distinct
     for rel in rqlst.iget_nodes(Relation):
-        if getrschema(rel.r_type).symmetric and not rel.neged(strict=True):
+        if getrschema(rel.r_type).symmetric and not isinstance(rel.parent, Exists):
             for vref in rel.iget_nodes(VariableRef):
                 stinfo = vref.variable.stinfo
                 if not stinfo['constnode'] and stinfo['selected']:
@@ -135,7 +135,7 @@
             # priority should be given to relation which are not in inner queries
             # (eg exists)
             try:
-                stinfo['principal'] = _select_principal(var.sqlscope, joins)
+                stinfo['principal'] = _select_principal(var.scope, joins)
             except CantSelectPrincipal:
                 stinfo['invariant'] = False
     rqlst.need_distinct = need_distinct
@@ -146,7 +146,7 @@
 class CantSelectPrincipal(Exception):
     """raised when no 'principal' variable can be found"""
 
-def _select_principal(sqlscope, relations, _sort=lambda x:x):
+def _select_principal(scope, relations, _sort=lambda x:x):
     """given a list of rqlst relations, select one which will be used to
     represent an invariant variable (e.g. using on extremity of the relation
     instead of the variable's type table
@@ -161,7 +161,7 @@
             continue
         if rel.ored(traverse_scope=True):
             ored_rels.add(rel)
-        elif rel.sqlscope is sqlscope:
+        elif rel.scope is scope:
             return rel
         elif not rel.neged(traverse_scope=True):
             diffscope_rels.add(rel)
@@ -175,12 +175,12 @@
                     ored_rels.discard(rel1)
                     ored_rels.discard(rel2)
     for rel in _sort(ored_rels):
-        if rel.sqlscope is sqlscope:
+        if rel.scope is scope:
             return rel
         diffscope_rels.add(rel)
     # if DISTINCT query, can use variable from a different scope as principal
     # since introduced duplicates will be removed
-    if sqlscope.stmt.distinct and diffscope_rels:
+    if scope.stmt.distinct and diffscope_rels:
         return iter(_sort(diffscope_rels)).next()
     # XXX  could use a relation for a different scope if it can't generate
     # duplicates, so we would have to check cardinality
@@ -197,7 +197,7 @@
         if rel.operator() not in ('=', 'IS') \
                or not isinstance(rel.children[1].children[0], VariableRef):
             continue
-        if rel.sqlscope is rel.stmt:
+        if rel.scope is rel.stmt:
             return rel
         principal = rel
     if principal is None:
@@ -220,23 +220,6 @@
                     var._q_invariant = True
             else:
                 var._q_invariant = False
-        for rel in select.iget_nodes(Relation):
-            if rel.neged(strict=True) and not rel.is_types_restriction():
-                rschema = getrschema(rel.r_type)
-                if not rschema.final:
-                    # if one of the relation's variable is ambiguous but not
-                    # invariant, an intersection will be necessary
-                    for vref in rel.get_nodes(VariableRef):
-                        var = vref.variable
-                        if (not var._q_invariant and var.valuable_references() == 1
-                            and len(var.stinfo['possibletypes']) > 1):
-                            select.need_intersect = True
-                            break
-                    else:
-                        continue
-                    break
-        else:
-            select.need_intersect = False
 
 
 class SQLGenAnnotator(object):
@@ -270,7 +253,7 @@
     def is_ambiguous(self, var):
         # ignore has_text relation
         if len([rel for rel in var.stinfo['relations']
-                if rel.sqlscope is var.sqlscope and rel.r_type == 'has_text']) == 1:
+                if rel.scope is var.scope and rel.r_type == 'has_text']) == 1:
             return False
         try:
             data = var.stmt._deamb_data
@@ -353,7 +336,7 @@
         if isinstance(term, VariableRef) and self.is_ambiguous(term.variable):
             var = term.variable
             if len(var.stinfo['relations']) == 1 \
-                   or rel.sqlscope is var.sqlscope or rel.r_type == 'identity':
+                   or rel.scope is var.scope or rel.r_type == 'identity':
                 self.restrict(var, frozenset(etypes_func()))
                 try:
                     self.maydeambrels[var].add(rel)