diff -r 0aae5216f99e -r 3e133b29a1a4 server/rqlannotation.py --- 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)