diff --git a/__init__.py b/__init__.py
index 94259dfefe0e2f47665df4e10af15f12bebc3037_X19pbml0X18ucHk=..f5ddbb4c5bae95fc56eb97bcdc7ea322b755889a_X19pbml0X18ucHk= 100644
--- a/__init__.py
+++ b/__init__.py
@@ -80,7 +80,7 @@
             self.annotate(rqlst)
         rqlst.schema = self._annotator.schema
         return rqlst
-    
+
     def annotate(self, rqlst):
         self._annotator.annotate(rqlst)
 
@@ -97,7 +97,7 @@
                                  debug)
         finally:
             self._analyser_lock.release()
-            
+
     def compute_all_solutions(self, rqlst, uid_func_mapping=None, kwargs=None,
                           debug=False):
         """compute syntaxe tree solutions with all types restriction (eg
@@ -109,8 +109,8 @@
                                  debug)
         finally:
             self._itr_analyser_lock.release()
-    
-    
+
+
     def simplify(self, rqlst):
         """Simplify `rqlst` by rewriting non-final variables associated to a const
         node (if annotator say we can...)
@@ -161,7 +161,7 @@
                         else:
                             rhs = copy_uid_node(select, rhs, vconsts)
                             select.groupby[select.groupby.index(vref)] = rhs
-                            rhs.parent = select                            
+                            rhs.parent = select
                     elif rel is uidrel or rel.is_types_restriction():
                         # drop this relation
                         rel.parent.remove(rel)
@@ -173,6 +173,6 @@
                     select.stinfo['rewritten'][var.name] = vconsts
         if select.stinfo['rewritten'] and select.solutions:
             select.clean_solutions()
-        
+
     def compare(self, rqlstring1, rqlstring2):
         """Compare 2 RQL requests.
@@ -177,6 +177,6 @@
     def compare(self, rqlstring1, rqlstring2):
         """Compare 2 RQL requests.
-        
+
         Return True if both requests would return the same results.
         """
         from rql.compare import compare_tree
@@ -189,9 +189,9 @@
     vconsts.append(node)
     return node
 
-        
-def parse(rqlstring, print_errors=True): 
-    """Return a syntax tree created from a RQL string."""   
+
+def parse(rqlstring, print_errors=True):
+    """Return a syntax tree created from a RQL string."""
     from yapps.runtime import print_error, SyntaxError, NoMoreTokens
     from rql.parser import Hercule, HerculeScanner
     # make sure rql string ends with a semi-colon
diff --git a/nodes.py b/nodes.py
index 94259dfefe0e2f47665df4e10af15f12bebc3037_bm9kZXMucHk=..f5ddbb4c5bae95fc56eb97bcdc7ea322b755889a_bm9kZXMucHk= 100644
--- a/nodes.py
+++ b/nodes.py
@@ -42,7 +42,7 @@
                     timedelta: 'Interval',
                     }
 
-    
+
 try:
     from mx.DateTime import DateTimeType, DateTimeDeltaType, today, now
     KEYWORD_MAP = {'NOW' : now,
@@ -65,7 +65,7 @@
     if isinstance(var, Variable):
         return VariableRef(var, noautoref=1)
     assert isinstance(var, VariableRef)
-    return var    
+    return var
 
 def variable_refs(node):
     for vref in node.iget_nodes(VariableRef):
@@ -76,10 +76,10 @@
 class HSMixin(object):
     """mixin class for classes which may be the lhs or rhs of an expression"""
     __slots__ = ()
-    
+
     def relation(self):
         """return the parent relation where self occurs or None"""
         try:
             return self.parent.relation()
         except AttributeError:
             return None
@@ -80,10 +80,10 @@
     def relation(self):
         """return the parent relation where self occurs or None"""
         try:
             return self.parent.relation()
         except AttributeError:
             return None
-        
+
     def get_description(self):
         return self.get_type()
 
@@ -105,5 +105,5 @@
 class EditableMixIn(object):
     """mixin class to add edition functionalities to some nodes, eg root nodes
     (statement) and Exists nodes
-    """ 
+    """
     __slots__ = ()
@@ -109,5 +109,5 @@
     __slots__ = ()
-   
+
     @property
     def undo_manager(self):
         return self.root.undo_manager
@@ -133,7 +133,7 @@
             from rql.undo import RemoveNodeOperation
             self.undo_manager.add_operation(RemoveNodeOperation(node))
         node.parent.remove(node)
-    
+
     def add_restriction(self, relation):
         """add a restriction relation"""
         r = self.where
@@ -149,7 +149,7 @@
                 from rql.undo import AddNodeOperation
                 self.undo_manager.add_operation(AddNodeOperation(relation))
         return relation
-    
+
     def add_constant_restriction(self, var, rtype, value, ctype,
                                  operator='='):
         """builds a restriction node to express a constant restriction:
@@ -168,9 +168,9 @@
             value = iter(value).next()
         return self.add_restriction(make_relation(var, rtype, (value, ctype),
                                                   Constant, operator))
-        
-    def add_relation(self, lhsvar, rtype, rhsvar): 
+
+    def add_relation(self, lhsvar, rtype, rhsvar):
         """builds a restriction node to express '<var> eid <eid>'"""
         return self.add_restriction(make_relation(lhsvar, rtype, (rhsvar,),
                                                   VariableRef))
 
@@ -173,7 +173,7 @@
         """builds a restriction node to express '<var> eid <eid>'"""
         return self.add_restriction(make_relation(lhsvar, rtype, (rhsvar,),
                                                   VariableRef))
 
-    def add_eid_restriction(self, var, eid): 
+    def add_eid_restriction(self, var, eid):
         """builds a restriction node to express '<var> eid <eid>'"""
         return self.add_constant_restriction(var, 'eid', eid, 'Int')
@@ -178,6 +178,6 @@
         """builds a restriction node to express '<var> eid <eid>'"""
         return self.add_constant_restriction(var, 'eid', eid, 'Int')
-    
+
     def add_type_restriction(self, var, etype):
         """builds a restriction node to express : variable is etype"""
         return self.add_constant_restriction(var, 'is', etype, 'etype')
@@ -192,8 +192,8 @@
             self.set_aliases(aliases)
         if query is not None:
             self.set_query(query)
-            
+
     def set_aliases(self, aliases):
         self.aliases = aliases
         for node in aliases:
             node.parent = self
@@ -196,11 +196,11 @@
     def set_aliases(self, aliases):
         self.aliases = aliases
         for node in aliases:
             node.parent = self
-            
+
     def set_query(self, node):
         self.query = node
         node.parent = self
 
     def copy(self, stmt):
         return SubQuery([v.copy(stmt) for v in self.aliases], self.query.copy())
@@ -201,10 +201,10 @@
     def set_query(self, node):
         self.query = node
         node.parent = self
 
     def copy(self, stmt):
         return SubQuery([v.copy(stmt) for v in self.aliases], self.query.copy())
-    
+
     @property
     def children(self):
         return self.aliases + [self.query]
@@ -208,10 +208,10 @@
     @property
     def children(self):
         return self.aliases + [self.query]
-    
+
     def as_string(self, encoding=None, kwargs=None):
         return '%s BEING (%s)' % (','.join(v.name for v in self.aliases),
                                   self.query.as_string())
     def __repr__(self):
         return '%s BEING (%s)' % (','.join(repr(v) for v in self.aliases),
                                   repr(self.query))
@@ -212,10 +212,10 @@
     def as_string(self, encoding=None, kwargs=None):
         return '%s BEING (%s)' % (','.join(v.name for v in self.aliases),
                                   self.query.as_string())
     def __repr__(self):
         return '%s BEING (%s)' % (','.join(repr(v) for v in self.aliases),
                                   repr(self.query))
-    
+
 class And(BinaryNode):
     """a logical AND node (binary)"""
     __slots__ = ()
@@ -219,10 +219,10 @@
 class And(BinaryNode):
     """a logical AND node (binary)"""
     __slots__ = ()
-    
+
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         return '%s, %s' % (self.children[0].as_string(encoding, kwargs),
                            self.children[1].as_string(encoding, kwargs))
     def __repr__(self):
         return '%s AND %s' % (repr(self.children[0]), repr(self.children[1]))
@@ -223,9 +223,9 @@
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         return '%s, %s' % (self.children[0].as_string(encoding, kwargs),
                            self.children[1].as_string(encoding, kwargs))
     def __repr__(self):
         return '%s AND %s' % (repr(self.children[0]), repr(self.children[1]))
-    
+
     def ored(self, traverse_scope=False, _fromnode=None):
         return self.parent.ored(traverse_scope, _fromnode or self)
@@ -230,6 +230,6 @@
     def ored(self, traverse_scope=False, _fromnode=None):
         return self.parent.ored(traverse_scope, _fromnode or self)
-    
+
     def neged(self, traverse_scope=False, _fromnode=None):
         return self.parent.neged(traverse_scope, _fromnode or self)
 
@@ -233,7 +233,7 @@
     def neged(self, traverse_scope=False, _fromnode=None):
         return self.parent.neged(traverse_scope, _fromnode or self)
 
-    
+
 class Or(BinaryNode):
     """a logical OR node (binary)"""
     __slots__ = ()
@@ -237,7 +237,7 @@
 class Or(BinaryNode):
     """a logical OR node (binary)"""
     __slots__ = ()
-    
+
     def as_string(self, encoding=None, kwargs=None):
         return '(%s) OR (%s)' % (self.children[0].as_string(encoding, kwargs),
                                  self.children[1].as_string(encoding, kwargs))
@@ -241,6 +241,6 @@
     def as_string(self, encoding=None, kwargs=None):
         return '(%s) OR (%s)' % (self.children[0].as_string(encoding, kwargs),
                                  self.children[1].as_string(encoding, kwargs))
-    
+
     def __repr__(self):
         return '%s OR %s' % (repr(self.children[0]), repr(self.children[1]))
@@ -245,5 +245,5 @@
     def __repr__(self):
         return '%s OR %s' % (repr(self.children[0]), repr(self.children[1]))
-    
+
     def ored(self, traverse_scope=False, _fromnode=None):
         return self
@@ -248,6 +248,6 @@
     def ored(self, traverse_scope=False, _fromnode=None):
         return self
-    
+
     def neged(self, traverse_scope=False, _fromnode=None):
         return self.parent.neged(traverse_scope, _fromnode or self)
 
@@ -255,8 +255,8 @@
 class Not(Node):
     """a logical NOT node (unary)"""
     __slots__ = ()
-    
+
     def as_string(self, encoding=None, kwargs=None):
         if isinstance(self.children[0], (Exists, Relation)):
             return 'NOT %s' % self.children[0].as_string(encoding, kwargs)
         return 'NOT (%s)' % self.children[0].as_string(encoding, kwargs)
@@ -259,7 +259,7 @@
     def as_string(self, encoding=None, kwargs=None):
         if isinstance(self.children[0], (Exists, Relation)):
             return 'NOT %s' % self.children[0].as_string(encoding, kwargs)
         return 'NOT (%s)' % self.children[0].as_string(encoding, kwargs)
-    
+
     def __repr__(self, encoding=None, kwargs=None):
         return 'NOT (%s)' % repr(self.children[0])
@@ -264,6 +264,6 @@
     def __repr__(self, encoding=None, kwargs=None):
         return 'NOT (%s)' % repr(self.children[0])
-    
+
     @property
     def sqlscope(self):
         return self
@@ -267,7 +267,7 @@
     @property
     def sqlscope(self):
         return self
-    
+
     def ored(self, traverse_scope=False, _fromnode=None):
         # XXX consider traverse_scope ?
         return self.parent.ored(traverse_scope, _fromnode or self)
@@ -271,7 +271,7 @@
     def ored(self, traverse_scope=False, _fromnode=None):
         # XXX consider traverse_scope ?
         return self.parent.ored(traverse_scope, _fromnode or self)
-    
+
     def neged(self, traverse_scope=False, _fromnode=None, strict=False):
         return self
 
@@ -294,7 +294,7 @@
             self.set_where(restriction)
         else:
             self.query = None
-            
+
     def copy(self, stmt):
         new = self.query.copy(stmt)
         return Exists(new)
@@ -298,7 +298,7 @@
     def copy(self, stmt):
         new = self.query.copy(stmt)
         return Exists(new)
-    
+
     @property
     def children(self):
         return (self.query,)
@@ -307,6 +307,6 @@
         assert self.query is None
         self.query = node
         node.parent = self
-        
+
     def is_equivalent(self, other):
         raise NotImplementedError
@@ -311,6 +311,6 @@
     def is_equivalent(self, other):
         raise NotImplementedError
-                    
+
     def as_string(self, encoding=None, kwargs=None):
         content = self.query and self.query.as_string(encoding, kwargs)
         return 'EXISTS(%s)' % content
@@ -321,7 +321,7 @@
     def set_where(self, node):
         self.query = node
         node.parent = self
-    
+
     @property
     def where(self):
         return self.query
@@ -325,7 +325,7 @@
     @property
     def where(self):
         return self.query
-    
+
     def replace(self, oldnode, newnode):
         assert oldnode is self.query
         self.query = newnode
@@ -335,10 +335,10 @@
     def scope(self):
         return self
     sqlscope = scope
-    
+
     def ored(self, traverse_scope=False, _fromnode=None):
         if not traverse_scope:
             if _fromnode is not None: # stop here
                 return False
             return self.parent.ored(traverse_scope, self)
         return self.parent.ored(traverse_scope, _fromnode)
@@ -339,10 +339,10 @@
     def ored(self, traverse_scope=False, _fromnode=None):
         if not traverse_scope:
             if _fromnode is not None: # stop here
                 return False
             return self.parent.ored(traverse_scope, self)
         return self.parent.ored(traverse_scope, _fromnode)
-    
+
     def neged(self, traverse_scope=False, _fromnode=None, strict=False):
         if not traverse_scope:
             if _fromnode is not None: # stop here
@@ -352,8 +352,8 @@
             return isinstance(self.parent, Not)
         return self.parent.neged(traverse_scope, _fromnode)
 
-    
+
 class Relation(Node):
     """a RQL relation"""
     __slots__ = ('r_type', 'optional',
                  '_q_sqltable', '_q_needcast') # XXX cubicweb specific
@@ -356,10 +356,10 @@
 class Relation(Node):
     """a RQL relation"""
     __slots__ = ('r_type', 'optional',
                  '_q_sqltable', '_q_needcast') # XXX cubicweb specific
-    
+
     def __init__(self, r_type, optional=None):
         Node.__init__(self)
         self.r_type = r_type.encode()
         self.optional = None
         self.set_optional(optional)
@@ -361,9 +361,9 @@
     def __init__(self, r_type, optional=None):
         Node.__init__(self)
         self.r_type = r_type.encode()
         self.optional = None
         self.set_optional(optional)
-    
+
     def initargs(self, stmt):
         """return list of arguments to give to __init__ to clone this node"""
         return self.r_type, self.optional
@@ -367,10 +367,10 @@
     def initargs(self, stmt):
         """return list of arguments to give to __init__ to clone this node"""
         return self.r_type, self.optional
-        
+
     def is_equivalent(self, other):
         if not Node.is_equivalent(self, other):
             return False
         if self.r_type != other.r_type:
             return False
         return True
@@ -371,10 +371,10 @@
     def is_equivalent(self, other):
         if not Node.is_equivalent(self, other):
             return False
         if self.r_type != other.r_type:
             return False
         return True
-    
+
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         try:
@@ -398,7 +398,7 @@
                                            self.children[1])
         except IndexError:
             return 'Relation(%s)' % self.r_type
-    
+
     def set_optional(self, optional):
         assert optional in (None, 'left', 'right')
         if optional is not None:
@@ -406,7 +406,7 @@
                 self.optional = 'both'
             else:
                 self.optional = optional
-            
+
     def relation(self):
         """return the parent relation where self occurs or None"""
         return self
@@ -410,6 +410,6 @@
     def relation(self):
         """return the parent relation where self occurs or None"""
         return self
-    
+
     def ored(self, traverse_scope=False, _fromnode=None):
         return self.parent.ored(traverse_scope, _fromnode or self)
@@ -414,6 +414,6 @@
     def ored(self, traverse_scope=False, _fromnode=None):
         return self.parent.ored(traverse_scope, _fromnode or self)
-    
+
     def neged(self, traverse_scope=False, _fromnode=None, strict=False):
         if strict:
             return isinstance(self.parent, Not)
@@ -439,7 +439,7 @@
         if isinstance(rhs, Comparison):
             return rhs.operator
         return '='
-       
+
     def get_parts(self):
         """return the left hand side and the right hand side of this relation
         """
@@ -462,7 +462,7 @@
             root.undo_manager.add_operation(SetOptionalOperation(self, self.optional))
         self.optional= value
 
-    
+
 class Comparison(HSMixin, Node):
     """handle comparisons:
 
@@ -466,6 +466,6 @@
 class Comparison(HSMixin, Node):
     """handle comparisons:
 
-     <, <=, =, >=, > LIKE and ILIKE operators have a unique children.    
+     <, <=, =, >=, > LIKE and ILIKE operators have a unique children.
     """
     __slots__ = ('operator',)
@@ -470,9 +470,9 @@
     """
     __slots__ = ('operator',)
-    
+
     def __init__(self, operator, value=None):
         Node.__init__(self)
         if operator == '~=':
             operator = 'ILIKE'
         elif operator == '=' and isinstance(value, Constant) and \
                  value.type is None:
@@ -473,10 +473,10 @@
     def __init__(self, operator, value=None):
         Node.__init__(self)
         if operator == '~=':
             operator = 'ILIKE'
         elif operator == '=' and isinstance(value, Constant) and \
                  value.type is None:
-            operator = 'IS'            
+            operator = 'IS'
         assert operator in ('<', '<=', '=', '>=', '>', 'ILIKE', 'LIKE', 'IS'), operator
         self.operator = operator.encode()
         if value is not None:
@@ -490,7 +490,7 @@
         if not Node.is_equivalent(self, other):
             return False
         return self.operator == other.operator
-    
+
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         if len(self.children) == 0:
@@ -506,7 +506,7 @@
 
     def __repr__(self):
         return '%s %s' % (self.operator, ', '.join(repr(c) for c in self.children))
-    
+
 
 class MathExpression(HSMixin, BinaryNode):
     """Operators plus, minus, multiply, divide."""
@@ -534,7 +534,7 @@
     def __repr__(self):
         return '(%r %s %r)' % (self.children[0], self.operator,
                                self.children[1])
-    
+
     def get_type(self, solution=None, kwargs=None):
         """return the type of object returned by this function if known
 
@@ -558,7 +558,7 @@
             if sorted((lhstype, rhstype)) == ['Float', 'Int']:
                 return 'Float'
             raise CoercionError(key)
-        
+
     def get_description(self):
         """if there is a variable in the math expr used as rhs of a relation,
         return the name of this relation, else return the type of the math
@@ -571,7 +571,7 @@
                 return rtype
         return self.get_type()
 
-    
+
 class Function(HSMixin, Node):
     """Class used to deal with aggregat functions (sum, min, max, count, avg)
     and latter upper(), lower() and other RQL transformations functions
@@ -615,7 +615,7 @@
 
     def get_description(self):
         return self.descr().st_description(self)
-        
+
     def descr(self):
         """return the type of object returned by this function if known"""
         return function_description(self.name)
@@ -619,8 +619,8 @@
     def descr(self):
         """return the type of object returned by this function if known"""
         return function_description(self.name)
-        
-        
+
+
 class Constant(HSMixin, LeafNode):
     """String, Int, TRUE, FALSE, TODAY, NULL..."""
     __slots__ = ('value', 'type', 'uid', 'uidtype')
@@ -624,7 +624,7 @@
 class Constant(HSMixin, LeafNode):
     """String, Int, TRUE, FALSE, TODAY, NULL..."""
     __slots__ = ('value', 'type', 'uid', 'uidtype')
-    
+
     def __init__(self, value, c_type, _uid=False, _uidtype=None):
         assert c_type in CONSTANT_TYPES, "Error got c_type="+repr(c_type)
         LeafNode.__init__(self) # don't care about Node attributes
@@ -633,7 +633,7 @@
         # updated by the annotator/analyzer if necessary
         self.uid = _uid
         self.uidtype = _uidtype
-        
+
     def initargs(self, stmt):
         """return list of arguments to give to __init__ to clone this node"""
         return (self.value, self.type, self.uid, self.uidtype)
@@ -642,7 +642,7 @@
         if not LeafNode.is_equivalent(self, other):
             return False
         return self.type == other.type and self.value == other.value
-    
+
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string (an unicode string is
         returned if encoding is None)
@@ -674,7 +674,7 @@
                 return quote(self.value.encode(encoding))
             return uquote(self.value)
         return repr(self.value)
-        
+
     def __repr__(self):
         return self.as_string('utf8')
 
@@ -719,7 +719,7 @@
         if not LeafNode.is_equivalent(self, other):
             return False
         return self.name == other.name
-    
+
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         return self.name
@@ -723,9 +723,9 @@
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         return self.name
-    
+
     def __repr__(self):
         return 'VarRef(%#X) to %r' % (id(self), self.variable)
 
     def __cmp__(self, other):
         return not self.is_equivalent(other)
@@ -727,9 +727,9 @@
     def __repr__(self):
         return 'VarRef(%#X) to %r' % (id(self), self.variable)
 
     def __cmp__(self, other):
         return not self.is_equivalent(other)
-        
+
     def register_reference(self):
         self.variable.register_reference(self)
 
@@ -741,7 +741,7 @@
 
     def get_description(self):
         return self.variable.get_description()
-    
+
 
 class SortTerm(Node):
     """a sort term bind a variable to the boolean <asc>
@@ -755,7 +755,7 @@
         self.asc = asc
         if copy is None:
             self.append(variable)
-    
+
     def initargs(self, stmt):
         """return list of arguments to give to __init__ to clone this node"""
         return (None, self.asc, True)
@@ -769,8 +769,8 @@
         if self.asc:
             return '%s' % self.term
         return '%s DESC' % self.term
-    
+
     def __repr__(self):
         if self.asc:
             return '%r ASC' % self.term
         return '%r DESC' % self.term
@@ -773,6 +773,6 @@
     def __repr__(self):
         if self.asc:
             return '%r ASC' % self.term
         return '%r DESC' % self.term
-    
+
     @property
@@ -778,7 +778,7 @@
     @property
-    def term(self): 
+    def term(self):
         return self.children[0]
 
 
 
 ###############################################################################
@@ -780,8 +780,8 @@
         return self.children[0]
 
 
 
 ###############################################################################
-    
+
 class Referenceable(object):
     __slots__ = ('name', 'stinfo')
@@ -786,6 +786,6 @@
 class Referenceable(object):
     __slots__ = ('name', 'stinfo')
-        
+
     def __init__(self, name):
         self.name = name.strip().encode()
         # used to collect some global information about the syntax tree
@@ -797,7 +797,7 @@
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         return self.name
-        
+
     def register_reference(self, vref):
         """add a reference to this variable"""
         self.stinfo['references'].add(vref)
@@ -801,7 +801,7 @@
     def register_reference(self, vref):
         """add a reference to this variable"""
         self.stinfo['references'].add(vref)
-        
+
     def unregister_reference(self, vref):
         """remove a reference to this variable"""
         try:
@@ -839,7 +839,7 @@
             # constant node linked to an uid variable if any
             'constnode': None,
             })
-    
+
     def get_type(self, solution=None, kwargs=None):
         """return entity type of this object, 'Any' if not found"""
         if solution:
@@ -855,7 +855,7 @@
                 except: # CoertionError, AssertionError :(
                     pass
         return 'Any'
-    
+
     def get_description(self):
         """return :
         * the name of a relation where this variable is used as lhs,
@@ -913,7 +913,7 @@
                 return rel
         return None
 
-    
+
 class ColumnAlias(Referenceable):
     __slots__ = ('colnum', 'query',
                  '_q_sql', '_q_sqltable') # XXX ginco specific
@@ -921,10 +921,10 @@
         super(ColumnAlias, self).__init__(alias)
         self.colnum = int(colnum)
         self.query = query
-    
+
     def __repr__(self):
         return 'alias %s(%#X)' % (self.name, id(self))
 
     @property
     def schema(self):
         return self.query.root.schema
@@ -925,10 +925,10 @@
     def __repr__(self):
         return 'alias %s(%#X)' % (self.name, id(self))
 
     @property
     def schema(self):
         return self.query.root.schema
-    
+
     def get_type(self, solution=None, kwargs=None):
         """return entity type of this object, 'Any' if not found"""
         vtype = super(ColumnAlias, self).get_type(solution, kwargs)
@@ -938,7 +938,7 @@
                 if vtype != 'Any':
                     return vtype
         return vtype
-    
+
     def get_description(self):
         """return entity type of this object, 'Any' if not found"""
         vtype = super(ColumnAlias, self).get_description()
@@ -952,5 +952,5 @@
     # Variable compatibility
     def init_copy(self, old):
         pass
-    
+
     def set_scope(self, scopenode):
@@ -956,7 +956,7 @@
     def set_scope(self, scopenode):
-        pass    
+        pass
     def get_scope(self):
         return self.query
     scope = property(get_scope, set_scope)
     sqlscope = scope
     set_sqlscope = set_scope
@@ -958,11 +958,11 @@
     def get_scope(self):
         return self.query
     scope = property(get_scope, set_scope)
     sqlscope = scope
     set_sqlscope = set_scope
-    
-    
+
+
 class Variable(Referenceable):
     """
     a variable definition, should not be directly added to the syntax tree (use
     VariableRef instead)
@@ -965,9 +965,9 @@
 class Variable(Referenceable):
     """
     a variable definition, should not be directly added to the syntax tree (use
     VariableRef instead)
-    
+
     collects information about a variable use in a syntax tree
     """
     __slots__ = ('stmt',
                  '_q_invariant', '_q_sql', '_q_sqltable') # XXX ginco specific
@@ -970,9 +970,9 @@
     collects information about a variable use in a syntax tree
     """
     __slots__ = ('stmt',
                  '_q_invariant', '_q_sql', '_q_sqltable') # XXX ginco specific
-        
+
     def __init__(self, name):
         super(Variable, self).__init__(name)
         # reference to the selection
         self.stmt = None
@@ -975,11 +975,11 @@
     def __init__(self, name):
         super(Variable, self).__init__(name)
         # reference to the selection
         self.stmt = None
-        
+
     def __repr__(self):
         return '%s(%#X)' % (self.name, id(self))
 
     @property
     def schema(self):
         return self.stmt.root.schema
@@ -980,11 +980,11 @@
     def __repr__(self):
         return '%s(%#X)' % (self.name, id(self))
 
     @property
     def schema(self):
         return self.stmt.root.schema
-    
+
     def prepare_annotation(self):
         super(Variable, self).prepare_annotation()
         self.stinfo['scope'] = None
         self.stinfo['sqlscope'] = None
@@ -987,10 +987,10 @@
     def prepare_annotation(self):
         super(Variable, self).prepare_annotation()
         self.stinfo['scope'] = None
         self.stinfo['sqlscope'] = None
-        
+
     def _set_scope(self, key, scopenode):
         if scopenode is self.stmt or self.stinfo[key] is None:
             self.stinfo[key] = scopenode
         elif not (self.stinfo[key] is self.stmt or scopenode is self.stinfo[key]):
             self.stinfo[key] = common_parent(self.stinfo[key], scopenode).scope
@@ -992,7 +992,7 @@
     def _set_scope(self, key, scopenode):
         if scopenode is self.stmt or self.stinfo[key] is None:
             self.stinfo[key] = scopenode
         elif not (self.stinfo[key] is self.stmt or scopenode is self.stinfo[key]):
             self.stinfo[key] = common_parent(self.stinfo[key], scopenode).scope
-    
+
     def set_scope(self, scopenode):
@@ -998,5 +998,5 @@
     def set_scope(self, scopenode):
-        self._set_scope('scope', scopenode)            
+        self._set_scope('scope', scopenode)
     def get_scope(self):
         return self.stinfo['scope']
     scope = property(get_scope, set_scope)
@@ -1000,5 +1000,5 @@
     def get_scope(self):
         return self.stinfo['scope']
     scope = property(get_scope, set_scope)
-    
+
     def set_sqlscope(self, sqlscopenode):
@@ -1004,5 +1004,5 @@
     def set_sqlscope(self, sqlscopenode):
-        self._set_scope('sqlscope', sqlscopenode)            
+        self._set_scope('sqlscope', sqlscopenode)
     def get_sqlscope(self):
         return self.stinfo['sqlscope']
     sqlscope = property(get_sqlscope, set_sqlscope)
@@ -1011,7 +1011,7 @@
         # should copy variable's possibletypes on copy
         if not self.stinfo.get('possibletypes'):
             self.stinfo['possibletypes'] = old.stinfo.get('possibletypes')
-    
+
     def valuable_references(self):
         """return the number of "valuable" references :
         references is in selection or in a non type (is) relations
diff --git a/stmts.py b/stmts.py
index 94259dfefe0e2f47665df4e10af15f12bebc3037_c3RtdHMucHk=..f5ddbb4c5bae95fc56eb97bcdc7ea322b755889a_c3RtdHMucHk= 100644
--- a/stmts.py
+++ b/stmts.py
@@ -38,7 +38,7 @@
     solutions = ()   # list of possibles solutions for used variables
     _varmaker = None # variable names generator, built when necessary
     where = None     # where clause node
-    
+
     def __init__(self):
         # dictionnary of defined variables in the original RQL syntax tree
         self.defined_vars = {}
@@ -42,6 +42,6 @@
     def __init__(self):
         # dictionnary of defined variables in the original RQL syntax tree
         self.defined_vars = {}
-        
+
     def get_selected_variables(self):
         return self.selected_terms()
@@ -46,6 +46,6 @@
     def get_selected_variables(self):
         return self.selected_terms()
-        
+
     def set_where(self, node):
         self.where = node
         node.parent = self
@@ -49,7 +49,7 @@
     def set_where(self, node):
         self.where = node
         node.parent = self
-        
+
     def copy(self, copy_solutions=True, solutions=None):
         new = self.__class__()
         if self.schema is not None:
@@ -61,6 +61,6 @@
         return new
 
     # construction helper methods #############################################
-    
+
     def get_etype(self, name):
         """return the type object for the given entity's type name
@@ -65,6 +65,6 @@
     def get_etype(self, name):
         """return the type object for the given entity's type name
-        
+
         raise BadRQLQuery on unknown type
         """
         return nodes.Constant(name, 'etype')
@@ -68,6 +68,6 @@
         raise BadRQLQuery on unknown type
         """
         return nodes.Constant(name, 'etype')
-        
+
     def get_variable(self, name):
         """get a variable instance from its name
@@ -72,6 +72,6 @@
     def get_variable(self, name):
         """get a variable instance from its name
-        
+
         the variable is created if it doesn't exist yet
         """
         try:
@@ -91,7 +91,7 @@
         while name in self.defined_vars:
             name =  self._varmaker.next()
         return name
-        
+
     def make_variable(self):
         """create a new variable with an unique name for this tree"""
         var = self.get_variable(self.allocate_varname())
@@ -99,7 +99,7 @@
             from rql.undo import MakeVarOperation
             self.undo_manager.add_operation(MakeVarOperation(var))
         return var
-    
+
     def set_possible_types(self, solutions, kwargs=_MARKER, key='possibletypes'):
         if key == 'possibletypes':
             self.solutions = solutions
@@ -131,7 +131,7 @@
             print repr(self)
             raise
         return True
-        
+
 class Statement(object):
     """base class for statement nodes"""
 
@@ -139,10 +139,10 @@
     # used
     schema = None     # ISchema
     annotated = False # set by the annotator
-    
+
 #     def __init__(self):
 #         Node.__init__(self)
 #         # syntax tree meta-information
 #         self.stinfo = {}
 
     # navigation helper methods #############################################
@@ -143,11 +143,11 @@
 #     def __init__(self):
 #         Node.__init__(self)
 #         # syntax tree meta-information
 #         self.stinfo = {}
 
     # navigation helper methods #############################################
-    
+
     @property
     def root(self):
         """return the root node of the tree"""
         return self
@@ -150,8 +150,8 @@
     @property
     def root(self):
         """return the root node of the tree"""
         return self
-        
+
     @property
     def stmt(self):
         return self
@@ -160,6 +160,6 @@
     def scope(self):
         return self
     sqlscope = scope
-    
+
     def ored(self, traverse_scope=False, _fromnode=None):
         return None
@@ -164,6 +164,6 @@
     def ored(self, traverse_scope=False, _fromnode=None):
         return None
-    
+
     def neged(self, traverse_scope=False, _fromnode=None, strict=False):
         return None
 
@@ -205,7 +205,7 @@
         self.wrap_selects()
         self.children[0].set_offset(offset)
     offset = property(_get_offset, set_offset)
-        
+
     def _get_limit(self):
         warn('limit is now a Select node attribute', DeprecationWarning,
              stacklevel=2)
@@ -217,10 +217,10 @@
         self.wrap_selects()
         self.children[0].set_limit(limit)
     limit = property(_get_limit, set_limit)
-    
-    @property 
+
+    @property
     def root(self):
         """return the root node of the tree"""
         if self.parent is None:
             return self
         return self.parent.root
@@ -222,10 +222,10 @@
     def root(self):
         """return the root node of the tree"""
         if self.parent is None:
             return self
         return self.parent.root
-    
+
     def get_description(self):
         return [c.get_description() for c in self.children]
 
     # repr / as_string / copy #################################################
@@ -228,7 +228,7 @@
     def get_description(self):
         return [c.get_description() for c in self.children]
 
     # repr / as_string / copy #################################################
-    
+
     def __repr__(self):
         return '\nUNION\n'.join(repr(select) for select in self.children)
@@ -233,6 +233,6 @@
     def __repr__(self):
         return '\nUNION\n'.join(repr(select) for select in self.children)
-    
+
     def as_string(self, encoding=None, kwargs=None):
         """return the tree as an encoded rql string"""
         strings = [select.as_string(encoding, kwargs)
@@ -240,7 +240,7 @@
         if len(strings) == 1:
             return strings[0]
         return ' UNION '.join('(%s)' % part for part in strings)
-            
+
     def copy(self, copy_children=True):
         new = Union()
         if self.schema is not None:
@@ -262,7 +262,7 @@
         for select in self.children:
             change.update(select.get_variable_variables(values))
         return change
-    
+
     def _locate_subquery(self, col, etype, kwargs):
         if len(self.children) == 1 and not self.children[0].with_:
             return self.children[0]
@@ -315,7 +315,7 @@
         """reverts the tree as it was when save_state() was last called"""
         self.memorizing -= 1
         assert self.memorizing >= 0
-        self.undo_manager.recover()    
+        self.undo_manager.recover()
 
     def check_references(self):
         """test function"""
@@ -336,7 +336,7 @@
             self.undo_manager.add_operation(RemoveSelectOperation(self, select, idx))
         self.children.pop(idx)
 
-        
+
 class Select(Statement, nodes.EditableMixIn, ScopeNode):
     """the select node is the base statement of the syntax tree for selection
     statement, always child of a UNION root.
@@ -354,7 +354,7 @@
     with_ = ()
     # set by the annotator
     has_aggregat = False
-    
+
     def __init__(self):
         Statement.__init__(self)
         ScopeNode.__init__(self)
@@ -364,7 +364,7 @@
         # syntax tree meta-information
         self.stinfo = {'rewritten': {}}
 
-    @property 
+    @property
     def root(self):
         """return the root node of the tree"""
         return self.parent
@@ -368,7 +368,7 @@
     def root(self):
         """return the root node of the tree"""
         return self.parent
-                    
+
     def get_description(self):
         """return the list of types or relations (if not found) associated to
         selected variables
@@ -397,6 +397,6 @@
         return children
 
     # repr / as_string / copy #################################################
-    
+
     def __repr__(self):
         return self.as_string(userepr=True)
@@ -401,6 +401,6 @@
     def __repr__(self):
         return self.as_string(userepr=True)
-    
+
     def as_string(self, encoding=None, kwargs=None, userepr=False):
         """return the tree as an encoded rql string"""
         if userepr:
@@ -429,7 +429,7 @@
         if self.distinct:
             return 'DISTINCT Any ' + ' '.join(s)
         return 'Any ' + ' '.join(s)
-                                      
+
     def copy(self, copy_solutions=True, solutions=None):
         new = ScopeNode.copy(self, copy_solutions, solutions)
         if self.with_:
@@ -449,5 +449,5 @@
         new.offset = self.offset
         new.vargraph = self.vargraph
         return new
-    
+
     # select specific methods #################################################
@@ -453,5 +453,5 @@
     # select specific methods #################################################
-    
+
     def set_possible_types(self, solutions, kwargs=_MARKER, key='possibletypes'):
         super(Select, self).set_possible_types(solutions, kwargs, key)
         for ca in self.aliases.itervalues():
@@ -470,7 +470,7 @@
                     ca.query.remove_select(stmt)
                 else:
                     stmt.set_possible_types(sols)
-                                  
+
     def set_statement_type(self, etype):
         """set the statement type for this selection
         this method must be called last (i.e. once selected variables has been
@@ -481,10 +481,10 @@
         if etype != 'Any':
             for var in self.get_selected_variables():
                 self.add_type_restriction(var.variable, etype)
-    
+
     def set_distinct(self, value):
         """mark DISTINCT query"""
         if self.should_register_op and value != self.distinct:
             from rql.undo import SetDistinctOperation
             self.undo_manager.add_operation(SetDistinctOperation(self.distinct, self))
         self.distinct = value
@@ -485,10 +485,10 @@
     def set_distinct(self, value):
         """mark DISTINCT query"""
         if self.should_register_op and value != self.distinct:
             from rql.undo import SetDistinctOperation
             self.undo_manager.add_operation(SetDistinctOperation(self.distinct, self))
         self.distinct = value
-    
+
     def set_limit(self, limit):
         if limit is not None and (not isinstance(limit, (int, long)) or limit <= 0):
             raise BadRQLQuery('bad limit %s' % limit)
@@ -504,7 +504,7 @@
             from rql.undo import SetOffsetOperation
             self.undo_manager.add_operation(SetOffsetOperation(self.offset, self))
         self.offset = offset
-    
+
     def set_orderby(self, terms):
         self.orderby = terms
         for node in terms:
@@ -519,8 +519,8 @@
         self.having = terms
         for node in terms:
             node.parent = self
-            
+
     def set_with(self, terms, check=True):
         self.with_ = []
         for node in terms:
             self.add_subquery(node, check)
@@ -523,8 +523,8 @@
     def set_with(self, terms, check=True):
         self.with_ = []
         for node in terms:
             self.add_subquery(node, check)
-            
+
     def add_subquery(self, node, check=True):
         assert node.query
         if not isinstance(self.with_, list):
@@ -540,9 +540,9 @@
                 raise BadRQLQuery('Duplicated alias %s' % alias)
             ca = self.get_variable(alias, i)
             ca.query = node.query
-            
+
     def remove_subquery(self, node):
         self.with_.remove(node)
         node.parent = None
         for i, alias in enumerate(node.aliases):
             del self.aliases[alias.name]
@@ -544,8 +544,8 @@
     def remove_subquery(self, node):
         self.with_.remove(node)
         node.parent = None
         for i, alias in enumerate(node.aliases):
             del self.aliases[alias.name]
-            
+
     def get_variable(self, name, colnum=None):
         """get a variable instance from its name
@@ -550,6 +550,6 @@
     def get_variable(self, name, colnum=None):
         """get a variable instance from its name
-        
+
         the variable is created if it doesn't exist yet
         """
         if name in self.aliases:
@@ -564,7 +564,7 @@
                     vref.variable = calias
             return self.aliases[name]
         return super(Select, self).get_variable(name)
-    
+
     def clean_solutions(self, solutions=None):
         """when a rqlst has been extracted from another, this method returns
         solutions which make sense for this sub syntax tree
@@ -599,5 +599,5 @@
                 elif _values[vname] != etype:
                     change.add(vname)
         return change
-    
+
     # quick accessors #########################################################
@@ -603,5 +603,5 @@
     # quick accessors #########################################################
-        
+
     def get_selected_variables(self):
         """returns all selected variables, including those used in aggregate
         functions
@@ -611,7 +611,7 @@
                 yield node
 
     # construction helper methods #############################################
-    
+
     def save_state(self):
         """save the current tree"""
         self.parent.save_state()
@@ -625,7 +625,7 @@
             raise BadRQLQuery('Entity type are not allowed in selection')
         term.parent = self
         self.selection.append(term)
-            
+
     def replace(self, oldnode, newnode):
         assert oldnode is self.where
         self.where = newnode
@@ -637,7 +637,7 @@
 #             i = self.selection.index(oldnode)
 #             self.selection.pop(i)
 #             self.selection.insert(i, newnode)
-        
+
     def remove(self, node):
         if node is self.where:
             self.where = None
@@ -648,7 +648,7 @@
         else:
             raise Exception('duh XXX')
         node.parent = None
-        
+
     def undefine_variable(self, var):
         """undefine the given variable and remove all relations where it appears"""
         if hasattr(var, 'variable'):
@@ -736,7 +736,7 @@
     def remove_groups(self):
         for vref in self.groupby[:]:
             self.remove_group_var(vref)
-            
+
     def add_sort_var(self, var, asc=True):
         """add var in 'orderby' constraints
         asc is a boolean indicating the sort order (ascendent or descendent)
@@ -745,7 +745,7 @@
         vref.register_reference()
         term = nodes.SortTerm(vref, asc)
         self.add_sort_term(term)
-        
+
     def add_sort_term(self, term, index=None):
         if not self.orderby:
             self.orderby = []
@@ -767,7 +767,7 @@
         if self.orderby:
             for term in self.orderby[:]:
                 self.remove_sort_term(term)
-        
+
     def remove_sort_term(self, term):
         """remove a sort term and the sort node if necessary"""
         if self.should_register_op:
@@ -786,8 +786,8 @@
                     selection.append(vref)
         self.selection = selection
 
-    
+
 class Delete(Statement, ScopeNode):
     """the Delete node is the root of the syntax tree for deletion statement
     """
     TYPE = 'delete'
@@ -790,8 +790,8 @@
 class Delete(Statement, ScopeNode):
     """the Delete node is the root of the syntax tree for deletion statement
     """
     TYPE = 'delete'
-    
+
     def __init__(self):
         Statement.__init__(self)
         ScopeNode.__init__(self)
@@ -809,7 +809,7 @@
     @property
     def selection(self):
         return [vref for et, vref in self.main_variables]
-    
+
     def add_main_variable(self, etype, vref):
         """add a variable to the list of deleted variables"""
         #if etype == 'Any':
@@ -824,7 +824,7 @@
         assert isinstance(relation.children[1].children[0], nodes.VariableRef)
         relation.parent = self
         self.main_relations.append( relation )
-    
+
     # repr / as_string / copy #################################################
 
     def __repr__(self):
@@ -850,7 +850,7 @@
             if self.main_variables:
                 result.append(',')
             result.append(', '.join([rel.as_string(encoding, kwargs)
-                                     for rel in self.main_relations]))                
+                                     for rel in self.main_relations]))
         if self.where is not None:
             result.append('WHERE ' + self.where.as_string(encoding, kwargs))
         return ' '.join(result)
@@ -871,7 +871,7 @@
     """the Insert node is the root of the syntax tree for insertion statement
     """
     TYPE = 'insert'
-    
+
     def __init__(self):
         Statement.__init__(self)
         ScopeNode.__init__(self)
@@ -890,7 +890,7 @@
     @property
     def selection(self):
         return [vref for et, vref in self.main_variables]
-        
+
     def add_main_variable(self, etype, vref):
         """add a variable to the list of inserted variables"""
         if etype == 'Any':
@@ -898,7 +898,7 @@
         self.main_variables.append( (etype.encode(), vref) )
         vref.parent = self
         self.inserted_variables[vref.variable] = 1
-        
+
     def add_main_relation(self, relation):
         """add a relation to the list of inserted relations"""
         var = relation.children[0].variable
@@ -910,7 +910,7 @@
                 raise BadRQLQuery(msg % (var, var))
         relation.parent = self
         self.main_relations.append( relation )
-                              
+
     # repr / as_string / copy #################################################
 
     def __repr__(self):
@@ -948,7 +948,7 @@
             new.set_where(self.where.copy(new))
         return new
 
-        
+
 class Set(Statement, ScopeNode):
     """the Set node is the root of the syntax tree for update statement
     """
@@ -969,7 +969,7 @@
     @property
     def selection(self):
         return []
-        
+
     def add_main_relation(self, relation):
         """add a relation to the list of modified relations"""
         relation.parent = self