#759035: Automate addition of eid cachekey in RQL analysis
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 07 Apr 2010 14:26:35 +0200
changeset 5174 78438ad513ca
parent 5173 73760bbb66bd
child 5176 ddd5219d7eef
#759035: Automate addition of eid cachekey in RQL analysis
cwvreg.py
dbapi.py
devtools/repotest.py
devtools/testlib.py
entities/authobjs.py
entities/lib.py
entities/test/unittest_base.py
entities/test/unittest_wfobjs.py
entities/wfobjs.py
entity.py
hooks/email.py
hooks/integrity.py
hooks/metadata.py
hooks/notification.py
hooks/syncschema.py
hooks/syncsession.py
hooks/test/unittest_syncschema.py
misc/migration/postcreate.py
req.py
rset.py
schema.py
selectors.py
server/migractions.py
server/querier.py
server/repository.py
server/session.py
server/sources/ldapuser.py
server/sources/pyrorql.py
server/test/unittest_ldapuser.py
server/test/unittest_migractions.py
server/test/unittest_multisources.py
server/test/unittest_querier.py
server/test/unittest_repository.py
server/test/unittest_security.py
server/test/unittest_storage.py
server/test/unittest_undo.py
sobjects/test/unittest_supervising.py
test/unittest_entity.py
test/unittest_rset.py
transaction.py
web/application.py
web/component.py
web/facet.py
web/test/unittest_application.py
web/test/unittest_urlpublisher.py
web/test/unittest_views_basecontrollers.py
web/test/unittest_views_baseviews.py
web/views/autoform.py
web/views/basecontrollers.py
web/views/bookmark.py
web/views/editcontroller.py
web/views/urlpublishing.py
web/views/workflow.py
--- a/cwvreg.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/cwvreg.py	Wed Apr 07 14:26:35 2010 +0200
@@ -602,7 +602,7 @@
     def solutions(self, req, rqlst, args):
         def type_from_eid(eid, req=req):
             return req.describe(eid)[0]
-        self.rqlhelper.compute_solutions(rqlst, {'eid': type_from_eid}, args)
+        return self.rqlhelper.compute_solutions(rqlst, {'eid': type_from_eid}, args)
 
     def parse(self, req, rql, args=None):
         rqlst = self.rqlhelper.parse(rql)
--- a/dbapi.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/dbapi.py	Wed Apr 07 14:26:35 2010 +0200
@@ -14,6 +14,7 @@
 from logging import getLogger
 from time import time, clock
 from itertools import count
+from warnings import warn
 
 from logilab.common.logging_ext import set_log_methods
 from logilab.common.decorators import monkeypatch
@@ -282,9 +283,11 @@
         if user:
             self.set_entity_cache(user)
 
-    def execute(self, *args, **kwargs):
-        """Session interface compatibility"""
-        return self.cursor.execute(*args, **kwargs)
+    def execute(self, rql, args=None, eid_key=None, build_descr=True):
+        if eid_key is not None:
+            warn('[3.8] eid_key is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
+        return self.cursor.execute(rql, args, build_descr=build_descr)
 
 set_log_methods(DBAPIRequest, getLogger('cubicweb.dbapi'))
 
@@ -706,34 +709,42 @@
         self._closed = True
 
 
-    def execute(self, operation, parameters=None, eid_key=None, build_descr=True):
-        """Prepare and execute a database operation (query or command).
-        Parameters may be provided as sequence or mapping and will be bound to
-        variables in the operation.  Variables are specified in a
-        database-specific notation (see the module's paramstyle attribute for
-        details).
+    def execute(self, rql, args=None, eid_key=None, build_descr=True):
+        """execute a rql query, return resulting rows and their description in
+        a :class:`~cubicweb.rset.ResultSet` object
+
+        * `rql` should be an Unicode string or a plain ASCII string, containing
+          the rql query
 
-        A reference to the operation will be retained by the cursor.  If the
-        same operation object is passed in again, then the cursor can optimize
-        its behavior.  This is most effective for algorithms where the same
-        operation is used, but different parameters are bound to it (many
-        times).
+        * `args` the optional args dictionary associated to the query, with key
+          matching named substitution in `rql`
+
+        * `build_descr` is a boolean flag indicating if the description should
+          be built on select queries (if false, the description will be en empty
+          list)
+
+        on INSERT queries, there will be one row for each inserted entity,
+        containing its eid
 
-        For maximum efficiency when reusing an operation, it is best to use the
-        setinputsizes() method to specify the parameter types and sizes ahead
-        of time.  It is legal for a parameter to not match the predefined
-        information; the implementation should compensate, possibly with a loss
-        of efficiency.
+        on SET queries, XXX describe
+
+        DELETE queries returns no result.
+
+        .. Note::
+          to maximize the rql parsing/analyzing cache performance, you should
+          always use substitute arguments in queries, i.e. avoid query such as::
+
+            execute('Any X WHERE X eid 123')
 
-        The parameters may also be specified as list of tuples to e.g. insert
-        multiple rows in a single operation, but this kind of usage is
-        depreciated: executemany() should be used instead.
+          use::
 
-        Return values are not defined by the DB-API, but this here it returns a
-        ResultSet object.
+            execute('Any X WHERE X eid %(x)s', {'x': 123})
         """
-        self._res = rset = self._repo.execute(self._sessid, operation,
-                                              parameters, eid_key, build_descr)
+        if eid_key is not None:
+            warn('[3.8] eid_key is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
+        self._res = rset = self._repo.execute(self._sessid, rql,
+                                              args, build_descr)
         rset.req = self.req
         self._index = 0
         return rset
--- a/devtools/repotest.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/devtools/repotest.py	Wed Apr 07 14:26:35 2010 +0200
@@ -233,8 +233,8 @@
         self._dumb_sessions.append(s)
         return s
 
-    def execute(self, rql, args=None, eid_key=None, build_descr=True):
-        return self.o.execute(self.session, rql, args, eid_key, build_descr)
+    def execute(self, rql, args=None, build_descr=True):
+        return self.o.execute(self.session, rql, args, build_descr)
 
     def commit(self):
         self.session.commit()
--- a/devtools/testlib.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/devtools/testlib.py	Wed Apr 07 14:26:35 2010 +0200
@@ -15,6 +15,7 @@
 from urllib import unquote
 from math import log
 from contextlib import contextmanager
+from warnings import warn
 
 import simplejson
 
@@ -289,7 +290,7 @@
                                  upassword=password, **kwargs)
         req.execute('SET X in_group G WHERE X eid %%(x)s, G name IN(%s)'
                     % ','.join(repr(g) for g in groups),
-                    {'x': user.eid}, 'x')
+                    {'x': user.eid})
         user.clear_related_cache('in_group', 'subject')
         if commit:
             req.cnx.commit()
@@ -328,8 +329,11 @@
         """executes <rql>, builds a resultset, and returns a couple (rset, req)
         where req is a FakeRequest
         """
+        if eidkey is not None:
+            warn('[3.8] eidkey is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
         req = req or self.request(rql=rql)
-        return self.cnx.cursor(req).execute(unicode(rql), args, eidkey)
+        return req.execute(unicode(rql), args)
 
     @nocoverage
     def commit(self):
@@ -350,14 +354,14 @@
     # # server side db api #######################################################
 
     def sexecute(self, rql, args=None, eid_key=None):
+        if eid_key is not None:
+            warn('[3.8] eid_key is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
         self.session.set_pool()
-        return self.session.execute(rql, args, eid_key)
+        return self.session.execute(rql, args)
 
     # other utilities #########################################################
 
-    def entity(self, rql, args=None, eidkey=None, req=None):
-        return self.execute(rql, args, eidkey, req=req).get_entity(0, 0)
-
     @contextmanager
     def temporary_appobjects(self, *appobjects):
         self.vreg._loadedmods.setdefault(self.__module__, {})
@@ -681,29 +685,19 @@
 
     # deprecated ###############################################################
 
+    @deprecated('[3.8] use self.execute(...).get_entity(0, 0)')
+    def entity(self, rql, args=None, eidkey=None, req=None):
+        if eidkey is not None:
+            warn('[3.8] eidkey is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
+        return self.execute(rql, args, req=req).get_entity(0, 0)
+
     @deprecated('[3.6] use self.request().create_entity(...)')
     def add_entity(self, etype, req=None, **kwargs):
         if req is None:
             req = self.request()
         return req.create_entity(etype, **kwargs)
 
-    @deprecated('[3.4] use self.vreg["etypes"].etype_class(etype)(self.request())')
-    def etype_instance(self, etype, req=None):
-        req = req or self.request()
-        e = self.vreg['etypes'].etype_class(etype)(req)
-        e.eid = None
-        return e
-
-    @nocoverage
-    @deprecated('[3.4] use req = self.request(); rset = req.execute()',
-                stacklevel=3)
-    def rset_and_req(self, rql, optional_args=None, args=None, eidkey=None):
-        """executes <rql>, builds a resultset, and returns a
-        couple (rset, req) where req is a FakeRequest
-        """
-        return (self.execute(rql, args, eidkey),
-                self.request(rql=rql, **optional_args or {}))
-
 
 # auto-populating test classes and utilities ###################################
 
--- a/entities/authobjs.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/entities/authobjs.py	Wed Apr 07 14:26:35 2010 +0200
@@ -96,7 +96,7 @@
         try:
             return self._cw.execute(
                 'Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
-                {'x': eid, 'u': self.eid}, 'x')
+                {'x': eid, 'u': self.eid})
         except Unauthorized:
             return False
     owns = cached(owns, keyarg=1)
@@ -105,13 +105,11 @@
         rql = 'Any P WHERE P is CWPermission, U eid %(u)s, U in_group G, '\
               'P name %(pname)s, P require_group G'
         kwargs = {'pname': pname, 'u': self.eid}
-        cachekey = None
         if contexteid is not None:
             rql += ', X require_permission P, X eid %(x)s'
             kwargs['x'] = contexteid
-            cachekey = 'x'
         try:
-            return self._cw.execute(rql, kwargs, cachekey)
+            return self._cw.execute(rql, kwargs)
         except Unauthorized:
             return False
 
--- a/entities/lib.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/entities/lib.py	Wed Apr 07 14:26:35 2010 +0200
@@ -23,6 +23,7 @@
         return address
     return '%s at %s' % (name, host.replace('.', ' dot '))
 
+
 class EmailAddress(AnyEntity):
     __regid__ = 'EmailAddress'
     fetch_attrs, fetch_order = fetch_config(['address', 'alias'])
@@ -50,8 +51,10 @@
         subjrels = self.e_schema.object_relations()
         if not ('sender' in subjrels and 'recipients' in subjrels):
             return
-        rql = 'DISTINCT Any X, S, D ORDERBY D DESC WHERE X sender Y or X recipients Y, X subject S, X date D, Y eid %(y)s'
-        rset = self._cw.execute(rql, {'y': self.eid}, 'y')
+        rset = self._cw.execute('DISTINCT Any X, S, D ORDERBY D DESC '
+                                'WHERE X sender Y or X recipients Y, '
+                                'X subject S, X date D, Y eid %(y)s',
+                                {'y': self.eid})
         if skipeids is None:
             skipeids = set()
         for i in xrange(len(rset)):
@@ -131,7 +134,7 @@
 
     def touch(self):
         self._cw.execute('SET X timestamp %(t)s WHERE X eid %(x)s',
-                         {'t': datetime.now(), 'x': self.eid}, 'x')
+                         {'t': datetime.now(), 'x': self.eid})
 
     def valid(self, date):
         if date:
--- a/entities/test/unittest_base.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/entities/test/unittest_base.py	Wed Apr 07 14:26:35 2010 +0200
@@ -69,18 +69,18 @@
 class CWUserTC(BaseEntityTC):
 
     def test_complete(self):
-        e = self.entity('CWUser X WHERE X login "admin"')
+        e = self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
         e.complete()
 
     def test_matching_groups(self):
-        e = self.entity('CWUser X WHERE X login "admin"')
+        e = self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
         self.failUnless(e.matching_groups('managers'))
         self.failIf(e.matching_groups('xyz'))
         self.failUnless(e.matching_groups(('xyz', 'managers')))
         self.failIf(e.matching_groups(('xyz', 'abcd')))
 
     def test_dc_title_and_name(self):
-        e = self.entity('CWUser U WHERE U login "member"')
+        e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
         self.assertEquals(e.dc_title(), 'member')
         self.assertEquals(e.name(), 'member')
         e.set_attributes(firstname=u'bouah')
@@ -91,7 +91,7 @@
         self.assertEquals(e.name(), u'bouah lôt')
 
     def test_allowed_massmail_keys(self):
-        e = self.entity('CWUser U WHERE U login "member"')
+        e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
         # Bytes/Password attributes should be omited
         self.assertEquals(e.allowed_massmail_keys(),
                           set(('surname', 'firstname', 'login', 'last_login_time',
--- a/entities/test/unittest_wfobjs.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/entities/test/unittest_wfobjs.py	Wed Apr 07 14:26:35 2010 +0200
@@ -96,7 +96,7 @@
         self.assertEquals(e.latest_trinfo().comment, 'deactivate 2')
 
     def test_possible_transitions(self):
-        user = self.entity('CWUser X')
+        user = self.execute('CWUser X').get_entity(0, 0)
         trs = list(user.possible_transitions())
         self.assertEquals(len(trs), 1)
         self.assertEquals(trs[0].name, u'deactivate')
@@ -131,7 +131,7 @@
         with security_enabled(self.session, write=False):
             ex = self.assertRaises(ValidationError, self.session.execute,
                                'SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
-                               {'x': self.user().eid, 's': s.eid}, 'x')
+                               {'x': self.user().eid, 's': s.eid})
             self.assertEquals(ex.errors, {'in_state-subject': "state doesn't belong to entity's workflow. "
                                       "You may want to set a custom workflow for this entity first."})
 
@@ -413,7 +413,7 @@
         wf = add_wf(self, 'Company')
         wf.add_state('asleep', initial=True)
         self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
-                     {'wf': wf.eid, 'x': self.member.eid}, 'x')
+                     {'wf': wf.eid, 'x': self.member.eid})
         ex = self.assertRaises(ValidationError, self.commit)
         self.assertEquals(ex.errors, {'custom_workflow-subject': 'workflow isn\'t a workflow for this type'})
 
--- a/entities/wfobjs.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/entities/wfobjs.py	Wed Apr 07 14:26:35 2010 +0200
@@ -65,7 +65,7 @@
     def state_by_name(self, statename):
         rset = self._cw.execute('Any S, SN WHERE S name SN, S name %(n)s, '
                                 'S state_of WF, WF eid %(wf)s',
-                                {'n': statename, 'wf': self.eid}, 'wf')
+                                {'n': statename, 'wf': self.eid})
         if rset:
             return rset.get_entity(0, 0)
         return None
@@ -73,7 +73,7 @@
     def state_by_eid(self, eid):
         rset = self._cw.execute('Any S, SN WHERE S name SN, S eid %(s)s, '
                                 'S state_of WF, WF eid %(wf)s',
-                                {'s': eid, 'wf': self.eid}, ('wf', 's'))
+                                {'s': eid, 'wf': self.eid})
         if rset:
             return rset.get_entity(0, 0)
         return None
@@ -81,7 +81,7 @@
     def transition_by_name(self, trname):
         rset = self._cw.execute('Any T, TN WHERE T name TN, T name %(n)s, '
                                 'T transition_of WF, WF eid %(wf)s',
-                                {'n': trname, 'wf': self.eid}, 'wf')
+                                {'n': trname, 'wf': self.eid})
         if rset:
             return rset.get_entity(0, 0)
         return None
@@ -89,7 +89,7 @@
     def transition_by_eid(self, eid):
         rset = self._cw.execute('Any T, TN WHERE T name TN, T eid %(t)s, '
                                 'T transition_of WF, WF eid %(wf)s',
-                                {'t': eid, 'wf': self.eid}, ('wf', 't'))
+                                {'t': eid, 'wf': self.eid})
         if rset:
             return rset.get_entity(0, 0)
         return None
@@ -100,12 +100,12 @@
         """add a state to this workflow"""
         state = self._cw.create_entity('State', name=unicode(name), **kwargs)
         self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
-                         {'s': state.eid, 'wf': self.eid}, ('s', 'wf'))
+                         {'s': state.eid, 'wf': self.eid})
         if initial:
             assert not self.initial, "Initial state already defined as %s" % self.initial
             self._cw.execute('SET WF initial_state S '
                              'WHERE S eid %(s)s, WF eid %(wf)s',
-                             {'s': state.eid, 'wf': self.eid}, ('s', 'wf'))
+                             {'s': state.eid, 'wf': self.eid})
         return state
 
     def _add_transition(self, trtype, name, fromstates,
@@ -113,7 +113,7 @@
         tr = self._cw.create_entity(trtype, name=unicode(name), **kwargs)
         self._cw.execute('SET T transition_of WF '
                          'WHERE T eid %(t)s, WF eid %(wf)s',
-                         {'t': tr.eid, 'wf': self.eid}, ('t', 'wf'))
+                         {'t': tr.eid, 'wf': self.eid})
         assert fromstates, fromstates
         if not isinstance(fromstates, (tuple, list)):
             fromstates = (fromstates,)
@@ -122,7 +122,7 @@
                 state = state.eid
             self._cw.execute('SET S allowed_transition T '
                              'WHERE S eid %(s)s, T eid %(t)s',
-                             {'s': state, 't': tr.eid}, ('s', 't'))
+                             {'s': state, 't': tr.eid})
         tr.set_permissions(requiredgroups, conditions, reset=False)
         return tr
 
@@ -136,7 +136,7 @@
                 tostate = tostate.eid
             self._cw.execute('SET T destination_state S '
                              'WHERE S eid %(s)s, T eid %(t)s',
-                             {'t': tr.eid, 's': tostate}, ('s', 't'))
+                             {'t': tr.eid, 's': tostate})
         return tr
 
     def add_wftransition(self, name, subworkflow, fromstates, exitpoints=(),
@@ -147,7 +147,7 @@
         if hasattr(subworkflow, 'eid'):
             subworkflow = subworkflow.eid
         assert self._cw.execute('SET T subworkflow WF WHERE WF eid %(wf)s,T eid %(t)s',
-                                {'t': tr.eid, 'wf': subworkflow}, ('wf', 't'))
+                                {'t': tr.eid, 'wf': subworkflow})
         for fromstate, tostate in exitpoints:
             tr.add_exit_point(fromstate, tostate)
         return tr
@@ -159,11 +159,11 @@
         if not hasattr(replacement, 'eid'):
             replacement = self.state_by_name(replacement)
         execute = self._cw.execute
-        execute('SET X in_state S WHERE S eid %(s)s', {'s': todelstate.eid}, 's')
+        execute('SET X in_state S WHERE S eid %(s)s', {'s': todelstate.eid})
         execute('SET X from_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
-                {'os': todelstate.eid, 'ns': replacement.eid}, 's')
+                {'os': todelstate.eid, 'ns': replacement.eid})
         execute('SET X to_state NS WHERE X to_state OS, OS eid %(os)s, NS eid %(ns)s',
-                {'os': todelstate.eid, 'ns': replacement.eid}, 's')
+                {'os': todelstate.eid, 'ns': replacement.eid})
         todelstate.delete()
 
 
@@ -227,13 +227,13 @@
         """
         if reset:
             self._cw.execute('DELETE T require_group G WHERE T eid %(x)s',
-                             {'x': self.eid}, 'x')
+                             {'x': self.eid})
             self._cw.execute('DELETE T condition R WHERE T eid %(x)s',
-                             {'x': self.eid}, 'x')
+                             {'x': self.eid})
         for gname in requiredgroups:
             rset = self._cw.execute('SET T require_group G '
                                     'WHERE T eid %(x)s, G name %(gn)s',
-                                    {'x': self.eid, 'gn': gname}, 'x')
+                                    {'x': self.eid, 'gn': gname})
             assert rset, '%s is not a known group' % gname
         if isinstance(conditions, basestring):
             conditions = (conditions,)
@@ -247,7 +247,7 @@
             kwargs.setdefault('mainvars', u'X')
             self._cw.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
                              'X expression %(expr)s, X mainvars %(mainvars)s, '
-                             'T condition X WHERE T eid %(x)s',kwargs, 'x')
+                             'T condition X WHERE T eid %(x)s', kwargs)
         # XXX clear caches?
 
     @deprecated('[3.6.1] use set_permission')
@@ -299,15 +299,14 @@
         if tostate is None:
             self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
                              'X subworkflow_state FS WHERE T eid %(t)s, FS eid %(fs)s',
-                             {'t': self.eid, 'fs': fromstate}, ('t', 'fs'))
+                             {'t': self.eid, 'fs': fromstate})
         else:
             if hasattr(tostate, 'eid'):
                 tostate = tostate.eid
             self._cw.execute('INSERT SubWorkflowExitPoint X: T subworkflow_exit X, '
                              'X subworkflow_state FS, X destination_state TS '
                              'WHERE T eid %(t)s, FS eid %(fs)s, TS eid %(ts)s',
-                             {'t': self.eid, 'fs': fromstate, 'ts': tostate},
-                             ('t', 'fs', 'ts'))
+                             {'t': self.eid, 'fs': fromstate, 'ts': tostate})
 
     def get_exit_point(self, entity, stateeid):
         """if state is an exit point, return its associated destination state"""
@@ -469,7 +468,7 @@
             'T type TT, T type %(type)s, '
             'T name TN, T transition_of WF, WF eid %(wfeid)s',
             {'x': self.current_state.eid, 'type': type,
-             'wfeid': self.current_workflow.eid}, 'x')
+             'wfeid': self.current_workflow.eid})
         for tr in rset.entities():
             if tr.may_be_fired(self.eid):
                 yield tr
--- a/entity.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/entity.py	Wed Apr 07 14:26:35 2010 +0200
@@ -500,7 +500,7 @@
                 continue
             rql = 'SET X %s V WHERE X eid %%(x)s, Y eid %%(y)s, Y %s V' % (
                 rschema.type, rschema.type)
-            execute(rql, {'x': self.eid, 'y': ceid}, ('x', 'y'))
+            execute(rql, {'x': self.eid, 'y': ceid})
             self.clear_related_cache(rschema.type, 'subject')
         for rschema in self.e_schema.object_relations():
             if rschema.meta:
@@ -518,7 +518,7 @@
                 continue
             rql = 'SET V %s X WHERE X eid %%(x)s, Y eid %%(y)s, V %s Y' % (
                 rschema.type, rschema.type)
-            execute(rql, {'x': self.eid, 'y': ceid}, ('x', 'y'))
+            execute(rql, {'x': self.eid, 'y': ceid})
             self.clear_related_cache(rschema.type, 'object')
 
     # data fetching methods ###################################################
@@ -620,8 +620,7 @@
             # if some outer join are included to fetch inlined relations
             rql = 'Any %s,%s %s' % (V, ','.join(var for attr, var in selected),
                                     ','.join(rql))
-            rset = self._cw.execute(rql, {'x': self.eid}, 'x',
-                                    build_descr=False)[0]
+            rset = self._cw.execute(rql, {'x': self.eid}, build_descr=False)[0]
             # handle attributes
             for i in xrange(1, lastattr):
                 self[str(selected[i-1][0])] = rset[i]
@@ -650,7 +649,7 @@
                 return None
             rql = "Any A WHERE X eid %%(x)s, X %s A" % name
             try:
-                rset = self._cw.execute(rql, {'x': self.eid}, 'x')
+                rset = self._cw.execute(rql, {'x': self.eid})
             except Unauthorized:
                 self[name] = value = None
             else:
@@ -681,7 +680,7 @@
             pass
         assert self.has_eid()
         rql = self.related_rql(rtype, role)
-        rset = self._cw.execute(rql, {'x': self.eid}, 'x')
+        rset = self._cw.execute(rql, {'x': self.eid})
         self.set_related_cache(rtype, role, rset)
         return self.related(rtype, role, limit, entities)
 
@@ -807,7 +806,7 @@
         if limit is not None:
             before, after = rql.split(' WHERE ', 1)
             rql = '%s LIMIT %s WHERE %s' % (before, limit, after)
-        return self._cw.execute(rql, args, tuple(args))
+        return self._cw.execute(rql, args)
 
     # relations cache handling ################################################
 
@@ -890,7 +889,7 @@
         # and now update the database
         kwargs['x'] = self.eid
         self._cw.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations),
-                         kwargs, 'x')
+                         kwargs)
         kwargs.pop('x')
         # update current local object _after_ the rql query to avoid
         # interferences between the query execution itself and the
@@ -913,13 +912,13 @@
                 restr = 'X %s Y' % attr
             if values is None:
                 self._cw.execute('DELETE %s WHERE X eid %%(x)s' % restr,
-                                 {'x': self.eid}, 'x')
+                                 {'x': self.eid})
                 continue
             if not isinstance(values, (tuple, list, set, frozenset)):
                 values = (values,)
             self._cw.execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
                 restr, ','.join(str(r.eid) for r in values)),
-                             {'x': self.eid}, 'x')
+                             {'x': self.eid})
 
     def delete(self, **kwargs):
         assert self.has_eid(), self.eid
--- a/hooks/email.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/email.py	Wed Apr 07 14:26:35 2010 +0200
@@ -28,7 +28,7 @@
         if self.condition():
             self.session.execute(
                 'SET X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % self.rtype,
-                {'x': self.entity.eid, 'y': self.email.eid}, 'x')
+                {'x': self.entity.eid, 'y': self.email.eid})
 
 
 class SetPrimaryEmailRelationOp(SetUseEmailRelationOp):
--- a/hooks/integrity.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/integrity.py	Wed Apr 07 14:26:35 2010 +0200
@@ -77,7 +77,7 @@
                 continue
             if rtype in pendingrtypes:
                 continue
-            if not session.execute(self.base_rql % rtype, {'x': eid}, 'x'):
+            if not session.execute(self.base_rql % rtype, {'x': eid}):
                 etype = session.describe(eid)[0]
                 _ = session._
                 msg = _('at least one relation %(rtype)s is required on '
@@ -304,7 +304,7 @@
             # don't do anything if the entity is being created or deleted
             if not (eid in pendingeids or eid in neweids):
                 etype = session.describe(eid)[0]
-                session.execute(self.base_rql % (etype, rtype), {'x': eid}, 'x')
+                session.execute(self.base_rql % (etype, rtype), {'x': eid})
 
 class _DelayedDeleteSEntityOp(_DelayedDeleteOp):
     """delete orphan subject entity of a composite relation"""
--- a/hooks/metadata.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/metadata.py	Wed Apr 07 14:26:35 2010 +0200
@@ -102,8 +102,7 @@
     def precommit_event(self):
         self.session.execute('SET X owned_by U WHERE C owned_by U, C eid %(c)s,'
                              'NOT EXISTS(X owned_by U, X eid %(x)s)',
-                             {'c': self.compositeeid, 'x': self.composedeid},
-                             ('c', 'x'))
+                             {'c': self.compositeeid, 'x': self.composedeid})
 
 
 class SyncCompositeOwner(MetaDataHook):
--- a/hooks/notification.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/notification.py	Wed Apr 07 14:26:35 2010 +0200
@@ -124,7 +124,7 @@
             rqlsel.append(var)
             rqlrestr.append('X %s %s' % (attr, var))
         rql = 'Any %s WHERE %s' % (','.join(rqlsel), ','.join(rqlrestr))
-        rset = session.execute(rql, {'x': self.entity.eid}, 'x')
+        rset = session.execute(rql, {'x': self.entity.eid})
         for i, attr in enumerate(attrs):
             oldvalue = rset[0][i]
             newvalue = self.entity[attr]
--- a/hooks/syncschema.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/syncschema.py	Wed Apr 07 14:26:35 2010 +0200
@@ -1004,7 +1004,7 @@
             DropRelationTable(session, rschema.type)
         # if this is the last instance, drop associated relation type
         if lastrel and not self.eidto in pendings:
-            execute('DELETE CWRType X WHERE X eid %(x)s', {'x': self.eidto}, 'x')
+            execute('DELETE CWRType X WHERE X eid %(x)s', {'x': self.eidto})
         MemSchemaRDefDel(session, (subjschema, rschema, objschema))
 
 
--- a/hooks/syncsession.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/syncsession.py	Wed Apr 07 14:26:35 2010 +0200
@@ -36,7 +36,7 @@
         no query should be emitted while comitting
         """
         rql = 'Any N WHERE G eid %(x)s, G name N'
-        result = session.execute(rql, {'x': kwargs['geid']}, 'x', build_descr=False)
+        result = session.execute(rql, {'x': kwargs['geid']}, build_descr=False)
         hook.Operation.__init__(self, session, *args, **kwargs)
         self.group = result[0][0]
 
@@ -216,7 +216,7 @@
         if not session.describe(eidfrom)[0] == 'CWProperty':
             return
         key, value = session.execute('Any K,V WHERE P eid %(x)s,P pkey K,P value V',
-                                     {'x': eidfrom}, 'x')[0]
+                                     {'x': eidfrom})[0]
         if session.vreg.property_info(key)['sitewide']:
             qname = role_name('for_user', 'subject')
             msg = session._("site-wide property can't be set for user")
@@ -234,7 +234,7 @@
     def __call__(self):
         session = self._cw
         key = session.execute('Any K WHERE P eid %(x)s, P pkey K',
-                              {'x': self.eidfrom}, 'x')[0][0]
+                              {'x': self.eidfrom})[0][0]
         session.transaction_data.setdefault('pendingrelations', []).append(
             (self.eidfrom, self.rtype, self.eidto))
         for session_ in get_user_sessions(session.repo, self.eidto):
--- a/hooks/test/unittest_syncschema.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/hooks/test/unittest_syncschema.py	Wed Apr 07 14:26:35 2010 +0200
@@ -32,17 +32,17 @@
 
     def _set_perms(self, eid):
         self.execute('SET X read_permission G WHERE X eid %(x)s, G is CWGroup',
-                     {'x': eid}, 'x')
+                     {'x': eid})
         self.execute('SET X add_permission G WHERE X eid %(x)s, G is CWGroup, G name "managers"',
-                     {'x': eid}, 'x')
+                     {'x': eid})
         self.execute('SET X delete_permission G WHERE X eid %(x)s, G is CWGroup, G name "owners"',
-                     {'x': eid}, 'x')
+                     {'x': eid})
 
     def _set_attr_perms(self, eid):
         self.execute('SET X read_permission G WHERE X eid %(x)s, G is CWGroup',
-                     {'x': eid}, 'x')
+                     {'x': eid})
         self.execute('SET X update_permission G WHERE X eid %(x)s, G is CWGroup, G name "managers"',
-                     {'x': eid}, 'x')
+                     {'x': eid})
 
     def test_base(self):
         schema = self.repo.schema
@@ -88,7 +88,7 @@
                                'WHERE RT name "concerne2", E name "CWUser"')[0][0]
         self._set_perms(rdefeid)
         self.commit()
-        self.execute('DELETE CWRelation X WHERE X eid %(x)s', {'x': concerne2_rdef_eid}, 'x')
+        self.execute('DELETE CWRelation X WHERE X eid %(x)s', {'x': concerne2_rdef_eid})
         self.commit()
         self.failUnless('concerne2' in schema['CWUser'].subject_relations())
         self.failIf('concerne2' in schema['Societe2'].subject_relations())
@@ -248,7 +248,7 @@
         attreid = self.execute('INSERT CWAttribute X: X cardinality "11", X defaultval "noname", X indexed TRUE, X relation_type RT, X from_entity E, X to_entity F '
                                'WHERE RT name "messageid", E name "BaseTransition", F name "String"')[0][0]
         assert self.execute('SET X read_permission Y WHERE X eid %(x)s, Y name "managers"',
-                     {'x': attreid}, 'x')
+                     {'x': attreid})
         self.commit()
         self.schema.rebuild_infered_relations()
         self.failUnless('Transition' in self.schema['messageid'].subjects())
@@ -299,10 +299,10 @@
         if not getattr(cstr, 'eid', None):
             self.skip('start me alone') # bug in schema reloading, constraint's eid not restored
         self.execute('SET X value %(v)s WHERE X eid %(x)s',
-                     {'x': cstr.eid, 'v': u"u'normal', u'auto', u'new'"}, 'x')
+                     {'x': cstr.eid, 'v': u"u'normal', u'auto', u'new'"})
         self.execute('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X '
                      'WHERE CT name %(ct)s, EDEF eid %(x)s',
-                     {'ct': 'SizeConstraint', 'value': u'max=10', 'x': rdef.eid}, 'x')
+                     {'ct': 'SizeConstraint', 'value': u'max=10', 'x': rdef.eid})
         self.commit()
         cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
         self.assertEquals(cstr.values, (u'normal', u'auto', u'new'))
--- a/misc/migration/postcreate.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/misc/migration/postcreate.py	Wed Apr 07 14:26:35 2010 +0200
@@ -43,7 +43,7 @@
 # need this since we already have at least one user in the database (the default admin)
 for user in rql('Any X WHERE X is CWUser').entities():
     rql('SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
-        {'x': user.eid, 's': activated.eid}, 'x')
+        {'x': user.eid, 's': activated.eid})
 
 # on interactive mode, ask for level 0 persistent options
 if interactive_mode:
@@ -55,11 +55,12 @@
             default = cfg.option_default(optname, optdict)
             # only record values differing from default
             if value != default:
-                rql('INSERT CWProperty X: X pkey %(k)s, X value %(v)s', {'k': key, 'v': value})
+                rql('INSERT CWProperty X: X pkey %(k)s, X value %(v)s',
+                    {'k': key, 'v': value})
 
 # add PERM_USE_TEMPLATE_FORMAT permission
 from cubicweb.schema import PERM_USE_TEMPLATE_FORMAT
 usetmplperm = create_entity('CWPermission', name=PERM_USE_TEMPLATE_FORMAT,
                             label=_('use template languages'))
 rql('SET X require_group G WHERE G name "managers", X eid %(x)s',
-    {'x': usetmplperm.eid}, 'x')
+    {'x': usetmplperm.eid})
--- a/req.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/req.py	Wed Apr 07 14:26:35 2010 +0200
@@ -137,7 +137,6 @@
         rql = 'INSERT %s X' % etype
         relations = []
         restrictions = set()
-        cachekey = []
         pending_relations = []
         for attr, value in kwargs.items():
             if isinstance(value, (tuple, list, set, frozenset)):
@@ -157,7 +156,6 @@
                 restriction = '%s eid %%(%s)s' % (rvar, attr)
                 if not restriction in restrictions:
                     restrictions.add(restriction)
-                cachekey.append(attr)
                 kwargs[attr] = value.eid
             else: # attribute
                 relations.append('X %s %%(%s)s' % (attr, attr))
@@ -165,7 +163,7 @@
             rql = '%s: %s' % (rql, ', '.join(relations))
         if restrictions:
             rql = '%s WHERE %s' % (rql, ', '.join(restrictions))
-        created = execute(rql, kwargs, cachekey).get_entity(0, 0)
+        created = execute(rql, kwargs).get_entity(0, 0)
         for attr, values in pending_relations:
             if attr.startswith('reverse_'):
                 restr = 'Y %s X' % attr[len('reverse_'):]
@@ -173,7 +171,7 @@
                 restr = 'X %s Y' % attr
             execute('SET %s WHERE X eid %%(x)s, Y eid IN (%s)' % (
                 restr, ','.join(str(r.eid) for r in values)),
-                    {'x': created.eid}, 'x', build_descr=False)
+                    {'x': created.eid}, build_descr=False)
         return created
 
     def ensure_ro_rql(self, rql):
--- a/rset.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/rset.py	Wed Apr 07 14:26:35 2010 +0200
@@ -31,14 +31,12 @@
     :type rql: str or unicode
     :ivar rql: the original RQL query string
     """
-    def __init__(self, results, rql, args=None, description=(), cachekey=None,
-                 rqlst=None):
+    def __init__(self, results, rql, args=None, description=(), rqlst=None):
         self.rows = results
         self.rowcount = results and len(results) or 0
         # original query and arguments
         self.rql = rql
         self.args = args
-        self.cachekey = cachekey
         # entity types for each cell (same shape as rows)
         # maybe discarded if specified when the query has been executed
         self.description = description
--- a/schema.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/schema.py	Wed Apr 07 14:26:35 2010 +0200
@@ -705,14 +705,14 @@
         if eidto is None:
             # checking constraint for an attribute relation
             restriction = 'S eid %(s)s, ' + self.restriction
-            args, ck = {'s': eidfrom}, 's'
+            args = {'s': eidfrom}
         else:
             restriction = 'S eid %(s)s, O eid %(o)s, ' + self.restriction
-            args, ck = {'s': eidfrom, 'o': eidto}, ('s', 'o')
+            args = {'s': eidfrom, 'o': eidto}
         rql = 'Any %s WHERE %s' % (self.mainvars,  restriction)
         if self.distinct_query:
             rql = 'DISTINCT ' + rql
-        return session.execute(rql, args, ck, build_descr=False)
+        return session.execute(rql, args, build_descr=False)
 
 
 class RQLConstraint(RepoEnforcedRQLConstraintMixIn, RQLVocabularyConstraint):
@@ -839,9 +839,8 @@
             return False
         if keyarg is None:
             kwargs.setdefault('u', session.user.eid)
-            cachekey = kwargs.keys()
             try:
-                rset = session.execute(rql, kwargs, cachekey, build_descr=True)
+                rset = session.execute(rql, kwargs, build_descr=True)
             except NotImplementedError:
                 self.critical('cant check rql expression, unsupported rql %s', rql)
                 if self.eid is not None:
--- a/selectors.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/selectors.py	Wed Apr 07 14:26:35 2010 +0200
@@ -1030,7 +1030,7 @@
     def score(self, req, rset, row, col):
         try:
             return len(req.execute(self.rql, {'x': rset[row][col],
-                                              'u': req.user.eid}, 'x'))
+                                              'u': req.user.eid}))
         except Unauthorized:
             return 0
 
--- a/server/migractions.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/migractions.py	Wed Apr 07 14:26:35 2010 +0200
@@ -268,9 +268,9 @@
         if self.session:
             self.session.set_pool()
 
-    def rqlexecall(self, rqliter, cachekey=None, ask_confirm=True):
+    def rqlexecall(self, rqliter, ask_confirm=True):
         for rql, kwargs in rqliter:
-            self.rqlexec(rql, kwargs, cachekey, ask_confirm=ask_confirm)
+            self.rqlexec(rql, kwargs, ask_confirm=ask_confirm)
 
     @cached
     def _create_context(self):
@@ -361,14 +361,14 @@
             # handle groups
             newgroups = list(erschema.get_groups(action))
             for geid, gname in self.rqlexec('Any G, GN WHERE T %s G, G name GN, '
-                                            'T eid %%(x)s' % perm, {'x': teid}, 'x',
+                                            'T eid %%(x)s' % perm, {'x': teid},
                                             ask_confirm=False):
                 if not gname in newgroups:
                     if not confirm or self.confirm('Remove %s permission of %s to %s?'
                                                    % (action, erschema, gname)):
                         self.rqlexec('DELETE T %s G WHERE G eid %%(x)s, T eid %s'
                                      % (perm, teid),
-                                     {'x': geid}, 'x', ask_confirm=False)
+                                     {'x': geid}, ask_confirm=False)
                 else:
                     newgroups.remove(gname)
             for gname in newgroups:
@@ -376,7 +376,7 @@
                                                % (action, erschema, gname)):
                     self.rqlexec('SET T %s G WHERE G eid %%(x)s, T eid %s'
                                  % (perm, teid),
-                                 {'x': gm[gname]}, 'x', ask_confirm=False)
+                                 {'x': gm[gname]}, ask_confirm=False)
             # handle rql expressions
             newexprs = dict((expr.expression, expr) for expr in erschema.get_rqlexprs(action))
             for expreid, expression in self.rqlexec('Any E, EX WHERE T %s E, E expression EX, '
@@ -388,7 +388,7 @@
                         # deleting the relation will delete the expression entity
                         self.rqlexec('DELETE T %s E WHERE E eid %%(x)s, T eid %s'
                                      % (perm, teid),
-                                     {'x': expreid}, 'x', ask_confirm=False)
+                                     {'x': expreid}, ask_confirm=False)
                 else:
                     newexprs.pop(expression)
             for expression in newexprs.values():
@@ -399,7 +399,7 @@
                                  'X expression %%(expr)s, X mainvars %%(vars)s, T %s X '
                                  'WHERE T eid %%(x)s' % perm,
                                  {'expr': expr, 'exprtype': exprtype,
-                                  'vars': expression.mainvars, 'x': teid}, 'x',
+                                  'vars': expression.mainvars, 'x': teid},
                                  ask_confirm=False)
 
     def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True, syncprops=True):
@@ -524,14 +524,13 @@
                     newcstr = None
                 if newcstr is None:
                     self.rqlexec('DELETE X constrained_by C WHERE C eid %(x)s',
-                                 {'x': cstr.eid}, 'x',
-                                 ask_confirm=confirm)
+                                 {'x': cstr.eid}, ask_confirm=confirm)
                 else:
                     newconstraints.remove(newcstr)
                     value = unicode(newcstr.serialize())
                     if value != unicode(cstr.serialize()):
                         self.rqlexec('SET X value %(v)s WHERE X eid %(x)s',
-                                     {'x': cstr.eid, 'v': value}, 'x',
+                                     {'x': cstr.eid, 'v': value},
                                      ask_confirm=confirm)
             # 2. add new constraints
             cstrtype_map = self.cstrtype_mapping()
@@ -644,10 +643,10 @@
                         self.cmd_drop_relation_definition(
                             str(fromtype), rschema.type, str(totype))
         # execute post-remove files
-        for pack in reversed(removedcubes):
-            self.exec_event_script('postremove', self.config.cube_dir(pack))
+        for cube in reversed(removedcubes):
+            self.exec_event_script('postremove', self.config.cube_dir(cube))
             self.rqlexec('DELETE CWProperty X WHERE X pkey %(pk)s',
-                         {'pk': u'system.version.'+pack}, ask_confirm=False)
+                         {'pk': u'system.version.'+cube}, ask_confirm=False)
             self.commit()
 
     # schema migration actions ################################################
@@ -736,8 +735,8 @@
                 continue
             if instspschema.specializes() != eschema:
                 self.rqlexec('SET D specializes P WHERE D eid %(d)s, P name %(pn)s',
-                             {'d': instspschema.eid,
-                              'pn': eschema.type}, ask_confirm=confirm)
+                             {'d': instspschema.eid, 'pn': eschema.type},
+                             ask_confirm=confirm)
                 for rschema, tschemas, role in spschema.relation_definitions(True):
                     for tschema in tschemas:
                         if not tschema in instschema:
@@ -1073,12 +1072,12 @@
         for etype in wfof:
             rset = self.rqlexec(
                 'SET X workflow_of ET WHERE X eid %(x)s, ET name %(et)s',
-                {'x': wf.eid, 'et': etype}, 'x', ask_confirm=False)
+                {'x': wf.eid, 'et': etype}, ask_confirm=False)
             assert rset, 'unexistant entity type %s' % etype
             if default:
                 self.rqlexec(
                     'SET ET default_workflow X WHERE X eid %(x)s, ET name %(et)s',
-                    {'x': wf.eid, 'et': etype}, 'x', ask_confirm=False)
+                    {'x': wf.eid, 'et': etype}, ask_confirm=False)
         if commit:
             self.commit()
         return wf
@@ -1202,6 +1201,9 @@
     def rqlexec(self, rql, kwargs=None, cachekey=None, build_descr=True,
                 ask_confirm=True):
         """rql action"""
+        if cachekey is not None:
+            warn('[3.8] cachekey is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
         if not isinstance(rql, (tuple, list)):
             rql = ( (rql, kwargs), )
         res = None
@@ -1213,7 +1215,7 @@
                 msg = rql
             if not ask_confirm or self.confirm('Execute rql: %s ?' % msg):
                 try:
-                    res = execute(rql, kwargs, cachekey, build_descr=build_descr)
+                    res = execute(rql, kwargs, build_descr=build_descr)
                 except Exception, ex:
                     if self.confirm('Error: %s\nabort?' % ex):
                         raise
--- a/server/querier.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/querier.py	Wed Apr 07 14:26:35 2010 +0200
@@ -515,16 +515,20 @@
     def set_schema(self, schema):
         self.schema = schema
         repo = self._repo
+        # rql st and solution cache
+        self._rql_cache = Cache(repo.config['rql-cache-size'])
+        # rql cache key cache
+        self._rql_ck_cache = Cache(repo.config['rql-cache-size'])
+        # some cache usage stats
+        self.cache_hit, self.cache_miss = 0, 0
         # rql parsing / analysing helper
         self.solutions = repo.vreg.solutions
-        self._rql_cache = Cache(repo.config['rql-cache-size'])
-        self.cache_hit, self.cache_miss = 0, 0
+        rqlhelper = repo.vreg.rqlhelper
+        self._parse = rqlhelper.parse
+        self._annotate = rqlhelper.annotate
         # rql planner
         # note: don't use repo.sources, may not be built yet, and also "admin"
         #       isn't an actual source
-        rqlhelper = repo.vreg.rqlhelper
-        self._parse = rqlhelper.parse
-        self._annotate = rqlhelper.annotate
         if len([uri for uri in repo.config.sources() if uri != 'admin']) < 2:
             from cubicweb.server.ssplanner import SSPlanner
             self._planner = SSPlanner(schema, rqlhelper)
@@ -547,7 +551,7 @@
             return InsertPlan(self, rqlst, args, session)
         return ExecutionPlan(self, rqlst, args, session)
 
-    def execute(self, session, rql, args=None, eid_key=None, build_descr=True):
+    def execute(self, session, rql, args=None, build_descr=True):
         """execute a rql query, return resulting rows and their description in
         a `ResultSet` object
 
@@ -556,12 +560,6 @@
         * `build_descr` is a boolean flag indicating if the description should
           be built on select queries (if false, the description will be en empty
           list)
-        * `eid_key` must be both a key in args and a substitution in the rql
-          query. It should be used to enhance cacheability of rql queries.
-          It may be a tuple for keys in args.
-          `eid_key` must be provided in cases where a eid substitution is provided
-          and resolves ambiguities in the possible solutions inferred for each
-          variable in the query.
 
         on INSERT queries, there will be one row with the eid of each inserted
         entity
@@ -577,40 +575,33 @@
                 print '*'*80
             print 'querier input', rql, args
         # parse the query and binds variables
-        if eid_key is not None:
-            if not isinstance(eid_key, (tuple, list)):
-                eid_key = (eid_key,)
-            cachekey = [rql]
-            for key in eid_key:
-                try:
-                    etype = self._repo.type_from_eid(args[key], session)
-                except KeyError:
-                    raise QueryError('bad cache key %s (no value)' % key)
-                except TypeError:
-                    raise QueryError('bad cache key %s (value: %r)' % (
-                        key, args[key]))
-                except UnknownEid:
-                    # we want queries such as "Any X WHERE X eid 9999"
-                    # return an empty result instead of raising UnknownEid
-                    return empty_rset(rql, args)
-                cachekey.append(etype)
-                # ensure eid is correctly typed in args
-                args[key] = typed_eid(args[key])
-            cachekey = tuple(cachekey)
-        else:
+        try:
             cachekey = rql
-        try:
+            if args:
+                eidkeys = self._rql_ck_cache[rql]
+                if eidkeys:
+                    try:
+                        cachekey = self._repo.querier_cache_key(session, rql,
+                                                                args, eidkeys)
+                    except UnknownEid:
+                        # we want queries such as "Any X WHERE X eid 9999"
+                        # return an empty result instead of raising UnknownEid
+                        return empty_rset(rql, args)
             rqlst = self._rql_cache[cachekey]
             self.cache_hit += 1
         except KeyError:
             self.cache_miss += 1
             rqlst = self.parse(rql)
             try:
-                self.solutions(session, rqlst, args)
+                eidkeys = self.solutions(session, rqlst, args)
             except UnknownEid:
                 # we want queries such as "Any X WHERE X eid 9999" return an
                 # empty result instead of raising UnknownEid
                 return empty_rset(rql, args, rqlst)
+            self._rql_ck_cache[rql] = eidkeys
+            if eidkeys:
+                cachekey = self._repo.querier_cache_key(session, rql, args,
+                                                        eidkeys)
             self._rql_cache[cachekey] = rqlst
         orig_rqlst = rqlst
         if rqlst.TYPE != 'select':
@@ -670,7 +661,7 @@
             # FIXME: get number of affected entities / relations on non
             # selection queries ?
         # return a result set object
-        return ResultSet(results, rql, args, descr, eid_key, orig_rqlst)
+        return ResultSet(results, rql, args, descr, orig_rqlst)
 
 from logging import getLogger
 from cubicweb import set_log_methods
--- a/server/repository.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/repository.py	Wed Apr 07 14:26:35 2010 +0200
@@ -33,7 +33,7 @@
 from yams.schema import role_name
 from rql import RQLSyntaxError
 
-from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP,
+from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP, QueryError,
                       UnknownEid, AuthenticationError, ExecutionError,
                       ETypeNotSupportedBySources, MultiSourcesError,
                       BadConnectionId, Unauthorized, ValidationError,
@@ -76,12 +76,12 @@
             with security_enabled(session, read=False):
                 session.execute('DELETE X %s Y WHERE X eid %%(x)s, '
                                 'NOT Y eid %%(y)s' % rtype,
-                                {'x': eidfrom, 'y': eidto}, 'x')
+                                {'x': eidfrom, 'y': eidto})
     if card[1] in '1?':
         with security_enabled(session, read=False):
             session.execute('DELETE X %sY WHERE Y eid %%(y)s, '
                             'NOT X eid %%(x)s' % rtype,
-                            {'x': eidfrom, 'y': eidto}, 'y')
+                            {'x': eidfrom, 'y': eidto})
 
 
 class Repository(object):
@@ -408,7 +408,7 @@
         """return a CWUser entity for user with the given eid"""
         cls = self.vreg['etypes'].etype_class('CWUser')
         rql = cls.fetch_rql(session.user, ['X eid %(x)s'])
-        rset = session.execute(rql, {'x': eid}, 'x')
+        rset = session.execute(rql, {'x': eid})
         assert len(rset) == 1, rset
         cwuser = rset.get_entity(0, 0)
         # pylint: disable-msg=W0104
@@ -567,7 +567,7 @@
         session.commit()
         return session.id
 
-    def execute(self, sessionid, rqlstring, args=None, eid_key=None, build_descr=True):
+    def execute(self, sessionid, rqlstring, args=None, build_descr=True):
         """execute a RQL query
 
         * rqlstring should be an unicode string or a plain ascii string
@@ -578,7 +578,7 @@
         session = self._get_session(sessionid, setpool=True)
         try:
             try:
-                return self.querier.execute(session, rqlstring, args, eid_key,
+                return self.querier.execute(session, rqlstring, args,
                                             build_descr)
             except (Unauthorized, RQLSyntaxError):
                 raise
@@ -836,6 +836,21 @@
         """return the source for the given entity's eid"""
         return self.sources_by_uri[self.type_and_source_from_eid(eid, session)[1]]
 
+    def querier_cache_key(self, session, rql, args, eidkeys):
+        cachekey = [rql]
+        for key in sorted(eidkeys):
+            try:
+                etype = self.type_from_eid(args[key], session)
+            except KeyError:
+                raise QueryError('bad cache key %s (no value)' % key)
+            except TypeError:
+                raise QueryError('bad cache key %s (value: %r)' % (
+                    key, args[key]))
+            cachekey.append(etype)
+            # ensure eid is correctly typed in args
+            args[key] = typed_eid(args[key])
+        return tuple(cachekey)
+
     def eid2extid(self, source, eid, session=None):
         """get local id from an eid"""
         etype, uri, extid = self.type_and_source_from_eid(eid, session)
@@ -901,7 +916,7 @@
             else:
                 # minimal meta-data
                 session.execute('SET X is E WHERE X eid %(x)s, E name %(name)s',
-                                {'x': entity.eid, 'name': entity.__regid__}, 'x')
+                                {'x': entity.eid, 'name': entity.__regid__})
             session.commit(reset_pool)
             return eid
         except:
@@ -949,7 +964,7 @@
                     rql = 'DELETE X %s Y WHERE X eid %%(x)s' % rtype
                 else:
                     rql = 'DELETE Y %s X WHERE X eid %%(x)s' % rtype
-                session.execute(rql, {'x': eid}, 'x', build_descr=False)
+                session.execute(rql, {'x': eid}, build_descr=False)
         self.system_source.delete_info(session, entity, sourceuri, extid)
 
     def locate_relation_source(self, session, subject, rtype, object):
--- a/server/session.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/session.py	Wed Apr 07 14:26:35 2010 +0200
@@ -13,6 +13,7 @@
 import threading
 from time import time
 from uuid import uuid4
+from warnings import warn
 
 from logilab.common.deprecation import deprecated
 from rql.nodes import VariableRef, Function, ETYPE_PYOBJ_MAP, etype_from_pyobj
@@ -642,8 +643,14 @@
         return self.repo.source_from_eid(eid, self)
 
     def execute(self, rql, kwargs=None, eid_key=None, build_descr=True):
-        """db-api like method directly linked to the querier execute method"""
-        rset = self._execute(self, rql, kwargs, eid_key, build_descr)
+        """db-api like method directly linked to the querier execute method.
+
+        See :meth:`cubicweb.dbapi.Cursor.execute` documentation.
+        """
+        if eid_key is not None:
+            warn('[3.8] eid_key is deprecated, you can safely remove this argument',
+                 DeprecationWarning, stacklevel=2)
+        rset = self._execute(self, rql, kwargs, build_descr)
         rset.req = self
         return rset
 
--- a/server/sources/ldapuser.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/sources/ldapuser.py	Wed Apr 07 14:26:35 2010 +0200
@@ -230,10 +230,10 @@
                             elif rset:
                                 if not execute('SET X address %(addr)s WHERE '
                                                'U primary_email X, U eid %(u)s',
-                                               {'addr': ldapemailaddr, 'u': eid}, 'u'):
+                                               {'addr': ldapemailaddr, 'u': eid}):
                                     execute('SET X address %(addr)s WHERE '
                                             'X eid %(x)s',
-                                            {'addr': ldapemailaddr, 'x': rset[0][0]}, 'x')
+                                            {'addr': ldapemailaddr, 'x': rset[0][0]})
                             else:
                                 # no email found, create it
                                 _insert_email(session, ldapemailaddr, eid)
@@ -546,7 +546,7 @@
         super(LDAPUserSource, self).after_entity_insertion(session, dn, entity)
         for group in self.user_default_groups:
             session.execute('SET X in_group G WHERE X eid %(x)s, G name %(group)s',
-                            {'x': entity.eid, 'group': group}, 'x')
+                            {'x': entity.eid, 'group': group})
         # search for existant email first
         try:
             emailaddr = self._cache[dn][self.user_rev_attrs['email']]
@@ -556,7 +556,7 @@
                                {'addr': emailaddr})
         if rset:
             session.execute('SET U primary_email X WHERE U eid %(u)s, X eid %(x)s',
-                            {'x': rset[0][0], 'u': entity.eid}, 'u')
+                            {'x': rset[0][0], 'u': entity.eid})
         else:
             # not found, create it
             _insert_email(session, emailaddr, entity.eid)
@@ -571,7 +571,7 @@
 
 def _insert_email(session, emailaddr, ueid):
     session.execute('INSERT EmailAddress X: X address %(addr)s, U primary_email X '
-                    'WHERE U eid %(x)s', {'addr': emailaddr, 'x': ueid}, 'x')
+                    'WHERE U eid %(x)s', {'addr': emailaddr, 'x': ueid})
 
 class GotDN(Exception):
     """exception used when a dn localizing the searched user has been found"""
--- a/server/sources/pyrorql.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/sources/pyrorql.py	Wed Apr 07 14:26:35 2010 +0200
@@ -286,7 +286,7 @@
             session.set_shared_data('sources_error', msg % self.uri)
             return []
         try:
-            rql, cachekey = RQL2RQL(self).generate(session, union, args)
+            rql = RQL2RQL(self).generate(session, union, args)
         except UnknownEid, ex:
             if server.DEBUG:
                 print '  unknown eid', ex, 'no results'
@@ -294,7 +294,7 @@
         if server.DEBUG & server.DBG_RQL:
             print '  translated rql', rql
         try:
-            rset = cu.execute(rql, args, cachekey)
+            rset = cu.execute(rql, args)
         except Exception, ex:
             self.exception(str(ex))
             msg = session._("error while querying source %s, some data may be missing")
@@ -396,9 +396,8 @@
     def generate(self, session, rqlst, args):
         self._session = session
         self.kwargs = args
-        self.cachekey = []
         self.need_translation = False
-        return self.visit_union(rqlst), self.cachekey
+        return self.visit_union(rqlst)
 
     def visit_union(self, node):
         s = self._accept_children(node)
@@ -547,7 +546,6 @@
                 # ensure we have not yet translated the value...
                 if not key in self._const_var:
                     self.kwargs[key] = self.eid2extid(self.kwargs[key])
-                    self.cachekey.append(key)
                     self._const_var[key] = None
         return node.as_string()
 
--- a/server/test/unittest_ldapuser.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_ldapuser.py	Wed Apr 07 14:26:35 2010 +0200
@@ -176,7 +176,7 @@
             rset = self.sexecute('Any U ORDERBY D DESC WHERE WF wf_info_for X,'
                                 'WF creation_date D, WF from_state FS,'
                                 'WF owned_by U?, X eid %(x)s',
-                                {'x': adim.eid}, 'x')
+                                {'x': adim.eid})
             self.assertEquals(rset.rows, [[syt.eid]])
         finally:
             # restore db state
--- a/server/test/unittest_migractions.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_migractions.py	Wed Apr 07 14:26:35 2010 +0200
@@ -108,8 +108,8 @@
         testdate = date(2005, 12, 13)
         eid1 = self.mh.rqlexec('INSERT Note N')[0][0]
         eid2 = self.mh.rqlexec('INSERT Note N: N mydate %(mydate)s', {'mydate' : testdate})[0][0]
-        d1 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid1}, 'x')[0][0]
-        d2 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid2}, 'x')[0][0]
+        d1 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid1})[0][0]
+        d2 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid2})[0][0]
         self.assertEquals(d1, date.today())
         self.assertEquals(d2, testdate)
         self.mh.rollback()
@@ -503,13 +503,13 @@
         note = self.execute('INSERT Note X: X para "hip", X shortpara "hop", X newattr "momo"').get_entity(0, 0)
         aff = self.execute('INSERT Affaire X').get_entity(0, 0)
         self.failUnless(self.execute('SET X newnotinlined Y WHERE X eid %(x)s, Y eid %(y)s',
-                                     {'x': text.eid, 'y': aff.eid}, 'x'))
+                                     {'x': text.eid, 'y': aff.eid}))
         self.failUnless(self.execute('SET X newnotinlined Y WHERE X eid %(x)s, Y eid %(y)s',
-                                     {'x': note.eid, 'y': aff.eid}, 'x'))
+                                     {'x': note.eid, 'y': aff.eid}))
         self.failUnless(self.execute('SET X newinlined Y WHERE X eid %(x)s, Y eid %(y)s',
-                                     {'x': text.eid, 'y': aff.eid}, 'x'))
+                                     {'x': text.eid, 'y': aff.eid}))
         self.failUnless(self.execute('SET X newinlined Y WHERE X eid %(x)s, Y eid %(y)s',
-                                     {'x': note.eid, 'y': aff.eid}, 'x'))
+                                     {'x': note.eid, 'y': aff.eid}))
         # XXX remove specializes by ourselves, else tearDown fails when removing
         # Para because of Note inheritance. This could be fixed by putting the
         # MemSchemaCWETypeDel(session, name) operation in the
--- a/server/test/unittest_multisources.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_multisources.py	Wed Apr 07 14:26:35 2010 +0200
@@ -109,7 +109,7 @@
         self.assertEquals(metainf['type'], 'Card')
         self.assert_(metainf['extid'])
         etype = self.sexecute('Any ETN WHERE X is ET, ET name ETN, X eid %(x)s',
-                             {'x': externent.eid}, 'x')[0][0]
+                             {'x': externent.eid})[0][0]
         self.assertEquals(etype, 'Card')
 
     def test_order_limit_offset(self):
@@ -129,7 +129,7 @@
         self.sexecute('INSERT Affaire X: X ref "no readable card"')[0][0]
         aff1 = self.sexecute('INSERT Affaire X: X ref "card"')[0][0]
         # grant read access
-        self.sexecute('SET X owned_by U WHERE X eid %(x)s, U login "anon"', {'x': aff1}, 'x')
+        self.sexecute('SET X owned_by U WHERE X eid %(x)s, U login "anon"', {'x': aff1})
         self.commit()
         cnx = self.login('anon')
         cu = cnx.cursor()
@@ -139,8 +139,8 @@
 
     def test_synchronization(self):
         cu = cnx2.cursor()
-        assert cu.execute('Any X WHERE X eid %(x)s', {'x': self.aff1}, 'x')
-        cu.execute('SET X ref "BLAH" WHERE X eid %(x)s', {'x': self.aff1}, 'x')
+        assert cu.execute('Any X WHERE X eid %(x)s', {'x': self.aff1})
+        cu.execute('SET X ref "BLAH" WHERE X eid %(x)s', {'x': self.aff1})
         aff2 = cu.execute('INSERT Affaire X: X ref "AFFREUX"')[0][0]
         cnx2.commit()
         try:
@@ -155,20 +155,20 @@
             self.failIf(rset)
         finally:
             # restore state
-            cu.execute('SET X ref "AFFREF" WHERE X eid %(x)s', {'x': self.aff1}, 'x')
+            cu.execute('SET X ref "AFFREF" WHERE X eid %(x)s', {'x': self.aff1})
             cnx2.commit()
 
     def test_simplifiable_var(self):
         affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0]
         rset = self.sexecute('Any X,AA,AB WHERE E eid %(x)s, E in_state X, X name AA, X modification_date AB',
-                            {'x': affeid}, 'x')
+                            {'x': affeid})
         self.assertEquals(len(rset), 1)
         self.assertEquals(rset[0][1], "pitetre")
 
     def test_simplifiable_var_2(self):
         affeid = self.sexecute('Affaire X WHERE X ref "AFFREF"')[0][0]
         rset = self.sexecute('Any E WHERE E eid %(x)s, E in_state S, NOT S name "moved"',
-                            {'x': affeid, 'u': self.session.user.eid}, 'x')
+                            {'x': affeid, 'u': self.session.user.eid})
         self.assertEquals(len(rset), 1)
 
     def test_sort_func(self):
@@ -216,7 +216,7 @@
             rset = self.sexecute('Any X,Y WHERE X is Card, Y is Affaire, X title T, Y ref T')
             self.assertEquals(len(rset), 2, rset.rows)
         finally:
-            cu.execute('DELETE Card X WHERE X eid %(x)s', {'x': ec2}, 'x')
+            cu.execute('DELETE Card X WHERE X eid %(x)s', {'x': ec2})
             cnx2.commit()
 
     def test_attr_unification_neq_1(self):
@@ -258,15 +258,15 @@
         userstate = self.session.user.in_state[0]
         states.remove((userstate.eid, userstate.name))
         notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s',
-                                                       {'x': self.session.user.eid}, 'x'))
+                                                       {'x': self.session.user.eid}))
         self.assertSetEquals(notstates, states)
         aff1 = self.sexecute('Any X WHERE X is Affaire, X ref "AFFREF"')[0][0]
-        aff1stateeid, aff1statename = self.sexecute('Any S,SN WHERE X eid %(x)s, X in_state S, S name SN', {'x': aff1}, 'x')[0]
+        aff1stateeid, aff1statename = self.sexecute('Any S,SN WHERE X eid %(x)s, X in_state S, S name SN', {'x': aff1})[0]
         self.assertEquals(aff1statename, 'pitetre')
         states.add((userstate.eid, userstate.name))
         states.remove((aff1stateeid, aff1statename))
         notstates = set(tuple(x) for x in self.sexecute('Any S,SN WHERE S is State, S name SN, NOT X in_state S, X eid %(x)s',
-                                                       {'x': aff1}, 'x'))
+                                                       {'x': aff1}))
         self.assertSetEquals(notstates, states)
 
     def test_absolute_url_base_url(self):
--- a/server/test/unittest_querier.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_querier.py	Wed Apr 07 14:26:35 2010 +0200
@@ -220,13 +220,13 @@
 
     def test_typed_eid(self):
         # should return an empty result set
-        rset = self.execute('Any X WHERE X eid %(x)s', {'x': '1'}, 'x')
+        rset = self.execute('Any X WHERE X eid %(x)s', {'x': '1'})
         self.assertIsInstance(rset[0][0], (int, long))
 
     def test_bytes_storage(self):
         feid = self.execute('INSERT File X: X data_name "foo.pdf", X data_format "text/plain", X data %(data)s',
                             {'data': Binary("xxx")})[0][0]
-        fdata = self.execute('Any D WHERE X data D, X eid %(x)s', {'x': feid}, 'x')[0][0]
+        fdata = self.execute('Any D WHERE X data D, X eid %(x)s', {'x': feid})[0][0]
         self.assertIsInstance(fdata, Binary)
         self.assertEquals(fdata.getvalue(), 'xxx')
 
@@ -356,17 +356,17 @@
 
     def test_select_outer_join_optimized(self):
         peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
-        rset = self.execute('Any X WHERE X eid %(x)s, P? connait X', {'x':peid1}, 'x')
+        rset = self.execute('Any X WHERE X eid %(x)s, P? connait X', {'x':peid1})
         self.assertEquals(rset.rows, [[peid1]])
         rset = self.execute('Any X WHERE X eid %(x)s, X require_permission P?',
-                            {'x':peid1}, 'x')
+                            {'x':peid1})
         self.assertEquals(rset.rows, [[peid1]])
 
     def test_select_left_outer_join(self):
         rset = self.execute('DISTINCT Any G WHERE U? in_group G')
         self.assertEquals(len(rset), 4)
         rset = self.execute('DISTINCT Any G WHERE U? in_group G, U eid %(x)s',
-                            {'x': self.session.user.eid}, 'x')
+                            {'x': self.session.user.eid})
         self.assertEquals(len(rset), 4)
 
     def test_select_ambigous_outer_join(self):
@@ -374,7 +374,7 @@
         self.execute("INSERT Tag X: X name 'tagbis'")[0][0]
         geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
         self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
-                     {'g': geid, 't': teid}, 'g')
+                     {'g': geid, 't': teid})
         rset = self.execute("Any GN,TN ORDERBY GN WHERE T? tags G, T name TN, G name GN")
         self.failUnless(['users', 'tag'] in rset.rows)
         self.failUnless(['activated', None] in rset.rows)
@@ -882,7 +882,7 @@
     def test_insert_5bis(self):
         peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
         self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
-                     {'x': peid}, 'x')
+                     {'x': peid})
         rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
         self.assert_(rset.rows)
         self.assertEquals(rset.description, [('Personne', 'Societe',)])
@@ -1000,17 +1000,17 @@
         eid = self.execute("INSERT Folder T: T name 'toto'")[0][0]
         self.commit()
         # fill the cache
-        self.execute("Any X WHERE X eid %(x)s", {'x': eid}, 'x')
+        self.execute("Any X WHERE X eid %(x)s", {'x': eid})
         self.execute("Any X WHERE X eid %s" %eid)
-        self.execute("Folder X WHERE X eid %(x)s", {'x': eid}, 'x')
+        self.execute("Folder X WHERE X eid %(x)s", {'x': eid})
         self.execute("Folder X WHERE X eid %s" %eid)
         self.execute("DELETE Folder T WHERE T eid %s"%eid)
         self.commit()
-        rset = self.execute("Any X WHERE X eid %(x)s", {'x': eid}, 'x')
+        rset = self.execute("Any X WHERE X eid %(x)s", {'x': eid})
         self.assertEquals(rset.rows, [])
         rset = self.execute("Any X WHERE X eid %s" %eid)
         self.assertEquals(rset.rows, [])
-        rset = self.execute("Folder X WHERE X eid %(x)s", {'x': eid}, 'x')
+        rset = self.execute("Folder X WHERE X eid %(x)s", {'x': eid})
         self.assertEquals(rset.rows, [])
         rset = self.execute("Folder X WHERE X eid %s" %eid)
         self.assertEquals(rset.rows, [])
@@ -1086,7 +1086,7 @@
     def test_update_string_concat(self):
         beid = self.execute("INSERT Bookmark Y: Y title 'toto', Y path '/view'")[0][0]
         self.execute('SET X title XN + %(suffix)s WHERE X is Bookmark, X title XN', {'suffix': u'-moved'})
-        newname = self.execute('Any XN WHERE X eid %(x)s, X title XN', {'x': beid}, 'x')[0][0]
+        newname = self.execute('Any XN WHERE X eid %(x)s, X title XN', {'x': beid})[0][0]
         self.assertEquals(newname, 'toto-moved')
 
     def test_update_query_error(self):
@@ -1203,7 +1203,7 @@
                         'creation_date': '2000/07/03 11:00'})
         rset = self.execute('Any lower(N) ORDERBY LOWER(N) WHERE X is Tag, X name N,'
                             'X owned_by U, U eid %(x)s',
-                            {'x':self.session.user.eid}, 'x')
+                            {'x':self.session.user.eid})
         self.assertEquals(rset.rows, [[u'\xe9name0']])
 
 
@@ -1286,7 +1286,7 @@
         ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
         self.execute("SET E in_group G, E firstname %(firstname)s, E surname %(surname)s "
                       "WHERE E eid %(x)s, G name 'users'",
-                      {'x':ueid, 'firstname': u'jean', 'surname': u'paul'}, 'x')
+                      {'x':ueid, 'firstname': u'jean', 'surname': u'paul'})
 
     def test_nonregr_u_owned_by_u(self):
         ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto', X in_group G "
--- a/server/test/unittest_repository.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_repository.py	Wed Apr 07 14:26:35 2010 +0200
@@ -457,7 +457,7 @@
         # our sqlite datetime adapter is ignore seconds fraction, so we have to
         # ensure update is done the next seconds
         time.sleep(1 - (ts.second - int(ts.second)))
-        self.execute('SET X nom "tata" WHERE X eid %(x)s', {'x': eidp}, 'x')
+        self.execute('SET X nom "tata" WHERE X eid %(x)s', {'x': eidp})
         self.commit()
         self.assertEquals(len(self.execute('Personne X WHERE X has_text "tutu"')), 1)
         self.session.set_pool()
--- a/server/test/unittest_security.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_security.py	Wed Apr 07 14:26:35 2010 +0200
@@ -197,7 +197,7 @@
         # to actually get Unauthorized exception, try to delete a relation we can read
         self.restore_connection()
         eid = self.execute("INSERT Affaire X: X sujet 'pascool'")[0][0]
-        self.execute('SET X owned_by U WHERE X eid %(x)s, U login "iaminusersgrouponly"', {'x': eid}, 'x')
+        self.execute('SET X owned_by U WHERE X eid %(x)s, U login "iaminusersgrouponly"', {'x': eid})
         self.execute("SET A concerne S WHERE A sujet 'pascool', S is Societe")
         self.commit()
         cnx = self.login('iaminusersgrouponly')
@@ -214,7 +214,7 @@
         cnx = self.login('user')
         cu = cnx.cursor()
         cu.execute('SET X upassword %(passwd)s WHERE X eid %(x)s',
-                   {'x': ueid, 'passwd': 'newpwd'}, 'x')
+                   {'x': ueid, 'passwd': 'newpwd'})
         cnx.commit()
         cnx.close()
         cnx = self.login('user', password='newpwd')
@@ -224,7 +224,7 @@
         cnx = self.login('iaminusersgrouponly')
         cu = cnx.cursor()
         cu.execute('SET X upassword %(passwd)s WHERE X eid %(x)s',
-                   {'x': ueid, 'passwd': 'newpwd'}, 'x')
+                   {'x': ueid, 'passwd': 'newpwd'})
         self.assertRaises(Unauthorized, cnx.commit)
 
     # read security test
@@ -243,22 +243,22 @@
         cu = cnx.cursor()
         rset = cu.execute('Affaire X')
         self.assertEquals(rset.rows, [])
-        self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid}, 'x')
+        self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid})
         # cache test
-        self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid}, 'x')
+        self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x': eid})
         aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
         soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0]
         cu.execute("SET A concerne S WHERE A is Affaire, S is Societe")
         cnx.commit()
-        rset = cu.execute('Any X WHERE X eid %(x)s', {'x': aff2}, 'x')
+        rset = cu.execute('Any X WHERE X eid %(x)s', {'x': aff2})
         self.assertEquals(rset.rows, [[aff2]])
         # more cache test w/ NOT eid
-        rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': eid}, 'x')
+        rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': eid})
         self.assertEquals(rset.rows, [[aff2]])
-        rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': aff2}, 'x')
+        rset = cu.execute('Affaire X WHERE NOT X eid %(x)s', {'x': aff2})
         self.assertEquals(rset.rows, [])
         # test can't update an attribute of an entity that can't be readen
-        self.assertRaises(Unauthorized, cu.execute, 'SET X sujet "hacked" WHERE X eid %(x)s', {'x': eid}, 'x')
+        self.assertRaises(Unauthorized, cu.execute, 'SET X sujet "hacked" WHERE X eid %(x)s', {'x': eid})
 
 
     def test_entity_created_in_transaction(self):
@@ -270,7 +270,7 @@
             cu = cnx.cursor()
             aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
             # entity created in transaction are readable *by eid*
-            self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}, 'x'))
+            self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}))
             # XXX would be nice if it worked
             rset = cu.execute("Affaire X WHERE X sujet 'cool'")
             self.assertEquals(len(rset), 0)
@@ -281,18 +281,17 @@
     def test_read_erqlexpr_has_text1(self):
         aff1 = self.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
         card1 = self.execute("INSERT Card X: X title 'cool'")[0][0]
-        self.execute('SET X owned_by U WHERE X eid %(x)s, U login "iaminusersgrouponly"', {'x': card1}, 'x')
+        self.execute('SET X owned_by U WHERE X eid %(x)s, U login "iaminusersgrouponly"', {'x': card1})
         self.commit()
         cnx = self.login('iaminusersgrouponly')
         cu = cnx.cursor()
         aff2 = cu.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
         soc1 = cu.execute("INSERT Societe X: X nom 'chouette'")[0][0]
-        cu.execute("SET A concerne S WHERE A eid %(a)s, S eid %(s)s", {'a': aff2, 's': soc1},
-                   ('a', 's'))
+        cu.execute("SET A concerne S WHERE A eid %(a)s, S eid %(s)s", {'a': aff2, 's': soc1})
         cnx.commit()
-        self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x':aff1}, 'x')
-        self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}, 'x'))
-        self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':card1}, 'x'))
+        self.assertRaises(Unauthorized, cu.execute, 'Any X WHERE X eid %(x)s', {'x':aff1})
+        self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':aff2}))
+        self.failUnless(cu.execute('Any X WHERE X eid %(x)s', {'x':card1}))
         rset = cu.execute("Any X WHERE X has_text 'cool'")
         self.assertEquals(sorted(eid for eid, in rset.rows),
                           [card1, aff2])
@@ -347,7 +346,7 @@
         # only managers should be able to edit the 'test' attribute of Personne entities
         eid = self.execute("INSERT Personne X: X nom 'bidule', X web 'http://www.debian.org', X test TRUE")[0][0]
         self.commit()
-        self.execute('SET X test FALSE WHERE X eid %(x)s', {'x': eid}, 'x')
+        self.execute('SET X test FALSE WHERE X eid %(x)s', {'x': eid})
         self.commit()
         cnx = self.login('iaminusersgrouponly')
         cu = cnx.cursor()
@@ -357,11 +356,11 @@
         self.assertRaises(Unauthorized, cnx.commit)
         eid = cu.execute("INSERT Personne X: X nom 'bidule', X web 'http://www.debian.org'")[0][0]
         cnx.commit()
-        cu.execute('SET X test FALSE WHERE X eid %(x)s', {'x': eid}, 'x')
+        cu.execute('SET X test FALSE WHERE X eid %(x)s', {'x': eid})
         self.assertRaises(Unauthorized, cnx.commit)
-        cu.execute('SET X test TRUE WHERE X eid %(x)s', {'x': eid}, 'x')
+        cu.execute('SET X test TRUE WHERE X eid %(x)s', {'x': eid})
         self.assertRaises(Unauthorized, cnx.commit)
-        cu.execute('SET X web "http://www.logilab.org" WHERE X eid %(x)s', {'x': eid}, 'x')
+        cu.execute('SET X web "http://www.logilab.org" WHERE X eid %(x)s', {'x': eid})
         cnx.commit()
         cnx.close()
 
@@ -370,23 +369,23 @@
         note = self.execute("INSERT Note X: X para 'bidule'").get_entity(0, 0)
         self.commit()
         note.fire_transition('markasdone')
-        self.execute('SET X para "truc" WHERE X eid %(x)s', {'x': note.eid}, 'x')
+        self.execute('SET X para "truc" WHERE X eid %(x)s', {'x': note.eid})
         self.commit()
         cnx = self.login('iaminusersgrouponly')
         cu = cnx.cursor()
-        cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note.eid}, 'x')
+        cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note.eid})
         self.assertRaises(Unauthorized, cnx.commit)
         note2 = cu.execute("INSERT Note X: X para 'bidule'").get_entity(0, 0)
         cnx.commit()
         note2.fire_transition('markasdone')
         cnx.commit()
-        self.assertEquals(len(cu.execute('Any X WHERE X in_state S, S name "todo", X eid %(x)s', {'x': note2.eid}, 'x')),
+        self.assertEquals(len(cu.execute('Any X WHERE X in_state S, S name "todo", X eid %(x)s', {'x': note2.eid})),
                           0)
-        cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid}, 'x')
+        cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid})
         self.assertRaises(Unauthorized, cnx.commit)
         note2.fire_transition('redoit')
         cnx.commit()
-        cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid}, 'x')
+        cu.execute("SET X para 'chouette' WHERE X eid %(x)s", {'x': note2.eid})
         cnx.commit()
 
     def test_attribute_read_security(self):
@@ -447,13 +446,13 @@
         # should only be able to read the anonymous user, not another one
         origuser = self.adminsession.user
         self.assertRaises(Unauthorized,
-                          cu.execute, 'CWUser X WHERE X eid %(x)s', {'x': origuser.eid}, 'x')
+                          cu.execute, 'CWUser X WHERE X eid %(x)s', {'x': origuser.eid})
         # nothing selected, nothing updated, no exception raised
         #self.assertRaises(Unauthorized,
         #                  cu.execute, 'SET X login "toto" WHERE X eid %(x)s',
         #                  {'x': self.user.eid})
 
-        rset = cu.execute('CWUser X WHERE X eid %(x)s', {'x': anon.eid}, 'x')
+        rset = cu.execute('CWUser X WHERE X eid %(x)s', {'x': anon.eid})
         self.assertEquals(rset.rows, [[anon.eid]])
         # but can't modify it
         cu.execute('SET X login "toto" WHERE X eid %(x)s', {'x': anon.eid})
@@ -494,7 +493,7 @@
         self.assertRaises(Unauthorized, cu.execute,'DELETE B bookmarked_by U')
         self.assertRaises(Unauthorized,
                           cu.execute, 'SET B bookmarked_by U WHERE U eid %(x)s, B eid %(b)s',
-                          {'x': anoneid, 'b': beid1}, 'x')
+                          {'x': anoneid, 'b': beid1})
 
 
     def test_ambigous_ordered(self):
@@ -551,10 +550,10 @@
         aff.clear_related_cache('wf_info_for', role='object')
         self.assertRaises(Unauthorized,
                           self.execute, 'SET TI from_state S WHERE TI eid %(ti)s, S name "ben non"',
-                          {'ti': trinfo.eid}, 'ti')
+                          {'ti': trinfo.eid})
         self.assertRaises(Unauthorized,
                           self.execute, 'SET TI to_state S WHERE TI eid %(ti)s, S name "pitetre"',
-                          {'ti': trinfo.eid}, 'ti')
+                          {'ti': trinfo.eid})
 
 if __name__ == '__main__':
     unittest_main()
--- a/server/test/unittest_storage.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_storage.py	Wed Apr 07 14:26:35 2010 +0200
@@ -130,14 +130,14 @@
                             ' (Any D, X WHERE X eid %(x)s, X data D)'
                             '  UNION '
                             ' (Any D, X WHERE X eid %(x)s, X data D)'
-                            ')', {'x': f1.eid}, 'x')
+                            ')', {'x': f1.eid})
         self.assertEquals(len(rset), 2)
         self.assertEquals(rset[0][0], f1.eid)
         self.assertEquals(rset[1][0], f1.eid)
         self.assertEquals(rset[0][1].getvalue(), 'the-data')
         self.assertEquals(rset[1][1].getvalue(), 'the-data')
         rset = self.execute('Any X,LENGTH(D) WHERE X eid %(x)s, X data D',
-                            {'x': f1.eid}, 'x')
+                            {'x': f1.eid})
         self.assertEquals(len(rset), 1)
         self.assertEquals(rset[0][0], f1.eid)
         self.assertEquals(rset[0][1], len('the-data'))
@@ -145,7 +145,7 @@
                             ' (Any D, X WHERE X eid %(x)s, X data D)'
                             '  UNION '
                             ' (Any D, X WHERE X eid %(x)s, X data D)'
-                            ')', {'x': f1.eid}, 'x')
+                            ')', {'x': f1.eid})
         self.assertEquals(len(rset), 2)
         self.assertEquals(rset[0][0], f1.eid)
         self.assertEquals(rset[1][0], f1.eid)
@@ -153,7 +153,7 @@
         self.assertEquals(rset[1][1], len('the-data'))
         ex = self.assertRaises(QueryError, self.execute,
                                'Any X,UPPER(D) WHERE X eid %(x)s, X data D',
-                               {'x': f1.eid}, 'x')
+                               {'x': f1.eid})
         self.assertEquals(str(ex), 'UPPER can not be called on mapped attribute')
 
 
@@ -176,7 +176,7 @@
                      {'d': Binary('some other data'), 'f': f1.eid})
         self.assertEquals(f1.data.getvalue(), 'some other data')
         self.commit()
-        f2 = self.entity('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid})
+        f2 = self.execute('Any F WHERE F eid %(f)s, F is File', {'f': f1.eid}).get_entity(0, 0)
         self.assertEquals(f2.data.getvalue(), 'some other data')
 
 
--- a/server/test/unittest_undo.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/server/test/unittest_undo.py	Wed Apr 07 14:26:35 2010 +0200
@@ -144,8 +144,8 @@
         undotxuuid = self.commit()
         self.assertEquals(undotxuuid, None) # undo not undoable
         self.assertEquals(errors, [])
-        self.failUnless(self.execute('Any X WHERE X eid %(x)s', {'x': toto.eid}, 'x'))
-        self.failUnless(self.execute('Any X WHERE X eid %(x)s', {'x': e.eid}, 'x'))
+        self.failUnless(self.execute('Any X WHERE X eid %(x)s', {'x': toto.eid}))
+        self.failUnless(self.execute('Any X WHERE X eid %(x)s', {'x': e.eid}))
         self.failUnless(self.execute('Any X WHERE X has_text "toto@logilab"'))
         self.assertEquals(toto.state, 'activated')
         self.assertEquals(toto.get_email(), 'toto@logilab.org')
@@ -216,8 +216,8 @@
         errors = self.cnx.undo_transaction(txuuid)
         self.commit()
         self.failIf(errors)
-        self.failIf(self.execute('Any X WHERE X eid %(x)s', {'x': c.eid}, 'x'))
-        self.failIf(self.execute('Any X WHERE X eid %(x)s', {'x': p.eid}, 'x'))
+        self.failIf(self.execute('Any X WHERE X eid %(x)s', {'x': c.eid}))
+        self.failIf(self.execute('Any X WHERE X eid %(x)s', {'x': p.eid}))
         self.failIf(self.execute('Any X,Y WHERE X fiche Y'))
         self.session.set_pool()
         for eid in (p.eid, c.eid):
--- a/sobjects/test/unittest_supervising.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/sobjects/test/unittest_supervising.py	Wed Apr 07 14:26:35 2010 +0200
@@ -30,9 +30,9 @@
         # do some modification
         user = self.execute('INSERT CWUser X: X login "toto", X upassword "sosafe", X in_group G '
                             'WHERE G name "users"').get_entity(0, 0)
-        self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': user.eid}, 'x')
+        self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': user.eid})
         self.execute('DELETE Card B WHERE B title "une news !"')
-        self.execute('SET X bookmarked_by U WHERE X is Bookmark, U eid %(x)s', {'x': user.eid}, 'x')
+        self.execute('SET X bookmarked_by U WHERE X is Bookmark, U eid %(x)s', {'x': user.eid})
         self.execute('SET X content "duh?" WHERE X is Comment')
         self.execute('DELETE X comments Y WHERE Y is Card, Y title "une autre news !"')
         # check only one supervision email operation
@@ -91,7 +91,7 @@
     def test_nonregr1(self):
         session = self.session
         # do some unlogged modification
-        self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': session.user.eid}, 'x')
+        self.execute('SET X last_login_time NOW WHERE X eid %(x)s', {'x': session.user.eid})
         self.commit() # no crash
 
 
--- a/test/unittest_entity.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/test/unittest_entity.py	Wed Apr 07 14:26:35 2010 +0200
@@ -44,8 +44,8 @@
         p = req.create_entity('Personne', nom=u'toto')
         oe = req.create_entity('Note', type=u'x')
         self.execute('SET T ecrit_par U WHERE T eid %(t)s, U eid %(u)s',
-                     {'t': oe.eid, 'u': p.eid}, ('t','u'))
-        self.execute('SET TAG tags X WHERE X eid %(x)s', {'x': oe.eid}, 'x')
+                     {'t': oe.eid, 'u': p.eid})
+        self.execute('SET TAG tags X WHERE X eid %(x)s', {'x': oe.eid})
         e = req.create_entity('Note', type=u'z')
         e.copy_relations(oe.eid)
         self.assertEquals(len(e.ecrit_par), 1)
@@ -60,7 +60,7 @@
         oe = req.create_entity('Note', type=u'x')
         self.schema['ecrit_par'].rdef('Note', 'Personne').composite = 'subject'
         self.execute('SET T ecrit_par U WHERE T eid %(t)s, U eid %(u)s',
-                     {'t': oe.eid, 'u': p.eid}, ('t','u'))
+                     {'t': oe.eid, 'u': p.eid})
         e = req.create_entity('Note', type=u'z')
         e.copy_relations(oe.eid)
         self.failIf(e.ecrit_par)
@@ -69,12 +69,12 @@
     def test_copy_with_composite(self):
         user = self.user()
         adeleid = self.execute('INSERT EmailAddress X: X address "toto@logilab.org", U use_email X WHERE U login "admin"')[0][0]
-        e = self.entity('Any X WHERE X eid %(x)s', {'x':user.eid}, 'x')
+        e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
         self.assertEquals(e.use_email[0].address, "toto@logilab.org")
         self.assertEquals(e.use_email[0].eid, adeleid)
         usereid = self.execute('INSERT CWUser X: X login "toto", X upassword "toto", X in_group G '
                                'WHERE G name "users"')[0][0]
-        e = self.entity('Any X WHERE X eid %(x)s', {'x':usereid}, 'x')
+        e = self.execute('Any X WHERE X eid %(x)s', {'x': usereid}).get_entity(0, 0)
         e.copy_relations(user.eid)
         self.failIf(e.use_email)
         self.failIf(e.primary_email)
@@ -87,14 +87,14 @@
         user.fire_transition('deactivate')
         self.commit()
         eid2 = self.execute('INSERT CWUser X: X login "tutu", X upassword %(pwd)s', {'pwd': 'toto'})[0][0]
-        e = self.entity('Any X WHERE X eid %(x)s', {'x': eid2}, 'x')
+        e = self.execute('Any X WHERE X eid %(x)s', {'x': eid2}).get_entity(0, 0)
         e.copy_relations(user.eid)
         self.commit()
         e.clear_related_cache('in_state', 'subject')
         self.assertEquals(e.state, 'activated')
 
     def test_related_cache_both(self):
-        user = self.entity('Any X WHERE X eid %(x)s', {'x':self.user().eid}, 'x')
+        user = self.execute('Any X WHERE X eid %(x)s', {'x':self.user().eid}).get_entity(0, 0)
         adeleid = self.execute('INSERT EmailAddress X: X address "toto@logilab.org", U use_email X WHERE U login "admin"')[0][0]
         self.commit()
         self.assertEquals(user._related_cache, {})
@@ -235,7 +235,7 @@
         #rql = email.unrelated_rql('use_email', 'Person', 'object')[0]
         #self.assertEquals(rql, '')
         self.login('anon')
-        email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}, 'x').get_entity(0, 0)
+        email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
         rql = email.unrelated_rql('use_email', 'CWUser', 'object')[0]
         self.assertEquals(rql, 'Any S,AA,AB,AC,AD ORDERBY AA '
                           'WHERE NOT S use_email O, O eid %(x)s, S is CWUser, S login AA, S firstname AB, S surname AC, S modification_date AD, '
@@ -260,7 +260,7 @@
         unrelated = [r[0] for r in e.unrelated('tags', 'Personne', 'subject')]
         self.failUnless(p.eid in unrelated)
         self.execute('SET X tags Y WHERE X is Tag, Y is Personne')
-        e = self.entity('Any X WHERE X is Tag')
+        e = self.execute('Any X WHERE X is Tag').get_entity(0, 0)
         unrelated = [r[0] for r in e.unrelated('tags', 'Personne', 'subject')]
         self.failIf(p.eid in unrelated)
 
@@ -281,7 +281,7 @@
         self.assertEquals([x.address for x in rset.entities()], [u'hop'])
         self.create_user('toto')
         self.login('toto')
-        email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}, 'x').get_entity(0, 0)
+        email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
         rset = email.unrelated('use_email', 'CWUser', 'object')
         self.assertEquals([x.login for x in rset.entities()], ['toto'])
         user = self.request().user
@@ -291,7 +291,7 @@
         rset = user.unrelated('use_email', 'EmailAddress', 'subject')
         self.assertEquals([x.address for x in rset.entities()], [])
         self.login('anon')
-        email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}, 'x').get_entity(0, 0)
+        email = self.execute('Any X WHERE X eid %(x)s', {'x': email.eid}).get_entity(0, 0)
         rset = email.unrelated('use_email', 'CWUser', 'object')
         self.assertEquals([x.login for x in rset.entities()], [])
         user = self.request().user
@@ -439,7 +439,7 @@
         eid = session.execute(
             'INSERT TrInfo X: X comment "zou", X wf_info_for U, X from_state S1, X to_state S2 '
             'WHERE U login "admin", S1 name "activated", S2 name "deactivated"')[0][0]
-        trinfo = self.entity('Any X WHERE X eid %(x)s', {'x': eid}, 'x')
+        trinfo = self.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
         trinfo.complete()
         self.failUnless(isinstance(trinfo['creation_date'], datetime))
         self.failUnless(trinfo.relation_cached('from_state', 'subject'))
@@ -449,9 +449,9 @@
 
     def test_request_cache(self):
         req = self.request()
-        user = self.entity('CWUser X WHERE X login "admin"', req=req)
+        user = self.execute('CWUser X WHERE X login "admin"', req=req).get_entity(0, 0)
         state = user.in_state[0]
-        samestate = self.entity('State X WHERE X name "activated"', req=req)
+        samestate = self.execute('State X WHERE X name "activated"', req=req).get_entity(0, 0)
         self.failUnless(state is samestate)
 
     def test_rest_path(self):
@@ -481,7 +481,7 @@
         self.assertEquals(person.prenom, u'adrien')
         self.assertEquals(person.nom, u'di mascio')
         person.set_attributes(prenom=u'sylvain', nom=u'thénault')
-        person = self.entity('Personne P') # XXX retreival needed ?
+        person = self.execute('Personne P').get_entity(0, 0) # XXX retreival needed ?
         self.assertEquals(person.prenom, u'sylvain')
         self.assertEquals(person.nom, u'thénault')
 
--- a/test/unittest_rset.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/test/unittest_rset.py	Wed Apr 07 14:26:35 2010 +0200
@@ -212,7 +212,7 @@
     def test_get_entity_simple(self):
         self.request().create_entity('CWUser', login=u'adim', upassword='adim',
                         surname=u'di mascio', firstname=u'adrien')
-        e = self.entity('Any X,T WHERE X login "adim", X surname T')
+        e = self.execute('Any X,T WHERE X login "adim", X surname T').get_entity(0, 0)
         self.assertEquals(e['surname'], 'di mascio')
         self.assertRaises(KeyError, e.__getitem__, 'firstname')
         self.assertRaises(KeyError, e.__getitem__, 'creation_date')
--- a/transaction.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/transaction.py	Wed Apr 07 14:26:35 2010 +0200
@@ -48,7 +48,7 @@
         none if not found.
         """
         return self.req.execute('Any X WHERE X eid %(x)s',
-                                {'x': self.user_eid}, 'x').get_entity(0, 0)
+                                {'x': self.user_eid}).get_entity(0, 0)
 
     def actions_list(self, public=True):
         """return an ordered list of action effectued during that transaction
--- a/web/application.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/application.py	Wed Apr 07 14:26:35 2010 +0200
@@ -190,7 +190,7 @@
     def _update_last_login_time(self, req):
         try:
             req.execute('SET X last_login_time NOW WHERE X eid %(x)s',
-                        {'x' : req.user.eid}, 'x')
+                        {'x' : req.user.eid})
             req.cnx.commit()
         except (RepositoryError, Unauthorized):
             # ldap user are not writeable for instance
--- a/web/component.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/component.py	Wed Apr 07 14:26:35 2010 +0200
@@ -169,7 +169,7 @@
             rset = entity.related(self.rtype, role(self))
         else:
             eid = self.cw_rset[row][col]
-            rset = self._cw.execute(self.rql(), {'x': eid}, 'x')
+            rset = self._cw.execute(self.rql(), {'x': eid})
         if not rset.rowcount:
             return
         self.w(u'<div class="%s">' % self.div_class())
--- a/web/facet.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/facet.py	Wed Apr 07 14:26:35 2010 +0200
@@ -332,9 +332,9 @@
     def support_and(self):
         return False
 
-    def rqlexec(self, rql, args=None, cachekey=None):
+    def rqlexec(self, rql, args=None):
         try:
-            return self._cw.execute(rql, args, cachekey)
+            return self._cw.execute(rql, args)
         except Unauthorized:
             return []
 
@@ -375,7 +375,7 @@
             if self.target_type is not None:
                 rqlst.add_type_restriction(var, self.target_type)
             try:
-                rset = self.rqlexec(rqlst.as_string(), self.cw_rset.args, self.cw_rset.cachekey)
+                rset = self.rqlexec(rqlst.as_string(), self.cw_rset.args)
             except:
                 self.exception('error while getting vocabulary for %s, rql: %s',
                                self, rqlst.as_string())
@@ -464,7 +464,7 @@
             newvar = _prepare_vocabulary_rqlst(rqlst, mainvar, self.rtype, self.role)
             _set_orderby(rqlst, newvar, self.sortasc, self.sortfunc)
             try:
-                rset = self.rqlexec(rqlst.as_string(), self.cw_rset.args, self.cw_rset.cachekey)
+                rset = self.rqlexec(rqlst.as_string(), self.cw_rset.args)
             except:
                 self.exception('error while getting vocabulary for %s, rql: %s',
                                self, rqlst.as_string())
--- a/web/test/unittest_application.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/test/unittest_application.py	Wed Apr 07 14:26:35 2010 +0200
@@ -29,7 +29,7 @@
 class MockCursor:
     def __init__(self):
         self.executed = []
-    def execute(self, rql, args=None, cachekey=None):
+    def execute(self, rql, args=None, build_descr=False):
         args = args or {}
         self.executed.append(rql % args)
 
--- a/web/test/unittest_urlpublisher.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/test/unittest_urlpublisher.py	Wed Apr 07 14:26:35 2010 +0200
@@ -26,7 +26,7 @@
         req = self.request()
         b = req.create_entity('BlogEntry', title=u'hell\'o', content=u'blabla')
         c = req.create_entity('Tag', name=u'yo') # take care: Tag's name normalized to lower case
-        self.execute('SET C tags B WHERE C eid %(c)s, B eid %(b)s', {'c':c.eid, 'b':b.eid}, 'b')
+        self.execute('SET C tags B WHERE C eid %(c)s, B eid %(b)s', {'c':c.eid, 'b':b.eid})
 
     def process(self, url):
         req = self.req = self.request()
--- a/web/test/unittest_views_basecontrollers.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/test/unittest_views_basecontrollers.py	Wed Apr 07 14:26:35 2010 +0200
@@ -71,7 +71,7 @@
             'in_group-subject:'+eid:  groups,
             }
         path, params = self.expect_redirect_publish(req, 'edit')
-        e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}, 'x').get_entity(0, 0)
+        e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
         self.assertEquals(e.firstname, u'Sylvain')
         self.assertEquals(e.surname, u'Th\xe9nault')
         self.assertEquals(e.login, user.login)
@@ -111,7 +111,7 @@
             'surname-subject:'+eid:   u'Sylvain',
             }
         path, params = self.expect_redirect_publish(req, 'edit')
-        e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}, 'x').get_entity(0, 0)
+        e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
         self.assertEquals(e.login, user.login)
         self.assertEquals(e.firstname, u'Th\xe9nault')
         self.assertEquals(e.surname, u'Sylvain')
@@ -346,7 +346,7 @@
         self.assertIn('_cwmsgid', params)
         eid = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
         self.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
-                     {'x': self.session.user.eid, 'e': eid}, 'x')
+                     {'x': self.session.user.eid, 'e': eid})
         self.commit()
         req = req
         req.form = {'eid': u(eid), '__type:%s'%eid: 'EmailAddress',
@@ -385,7 +385,7 @@
             }
         try:
             path, params = self.expect_redirect_publish(req, 'edit')
-            e = self.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}, 'x').get_entity(0, 0)
+            e = self.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}).get_entity(0, 0)
             self.assertEquals(e.name, 'CWEType')
             self.assertEquals(sorted(g.eid for g in e.read_permission), groupeids)
         finally:
@@ -407,7 +407,7 @@
         path, params = self.expect_redirect_publish(req, 'edit')
         self.failUnless(path.startswith('blogentry/'))
         eid = path.split('/')[1]
-        e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}, 'x').get_entity(0, 0)
+        e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}).get_entity(0, 0)
         self.assertEquals(e.title, '"13:03:40"')
         self.assertEquals(e.content, '"13:03:43"')
 
--- a/web/test/unittest_views_baseviews.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/test/unittest_views_baseviews.py	Wed Apr 07 14:26:35 2010 +0200
@@ -90,7 +90,7 @@
         req = self.request()
         e = req.create_entity("State", name=u'<toto>', description=u'loo"ong blabla')
         rset = req.execute('Any X, D, CD, NOW - CD WHERE X is State, X description D, X creation_date CD, X eid %(x)s',
-                            {'x': e.eid}, 'x')
+                           {'x': e.eid})
         view = self.vreg['views'].select('table', req, rset=rset)
         return e, rset, view
 
--- a/web/views/autoform.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/views/autoform.py	Wed Apr 07 14:26:35 2010 +0200
@@ -289,7 +289,7 @@
     execute = req.execute
     for subj, rtype, obj in parse_relations_descr(rdefs):
         rql = 'DELETE X %s Y where X eid %%(x)s, Y eid %%(y)s' % rtype
-        execute(rql, {'x': subj, 'y': obj}, ('x', 'y'))
+        execute(rql, {'x': subj, 'y': obj})
     req.set_message(req._('relations deleted'))
 
 def insert_relations(req, rdefs):
@@ -297,7 +297,7 @@
     execute = req.execute
     for subj, rtype, obj in parse_relations_descr(rdefs):
         rql = 'SET X %s Y where X eid %%(x)s, Y eid %%(y)s' % rtype
-        execute(rql, {'x': subj, 'y': obj}, ('x', 'y'))
+        execute(rql, {'x': subj, 'y': obj})
 
 
 class GenericRelationsWidget(fw.FieldWidget):
--- a/web/views/basecontrollers.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/views/basecontrollers.py	Wed Apr 07 14:26:35 2010 +0200
@@ -180,7 +180,7 @@
             else:
                 rql = 'SET Y %s X WHERE X eid %%(x)s, Y eid %%(y)s' % rtype
             for teid in eids:
-                req.execute(rql, {'x': eid, 'y': typed_eid(teid)}, ('x', 'y'))
+                req.execute(rql, {'x': eid, 'y': typed_eid(teid)})
 
 
 def _validation_error(req, ex):
@@ -317,12 +317,12 @@
             form['__action_%s' % action] = u'whatever'
         return form
 
-    def _exec(self, rql, args=None, eidkey=None, rocheck=True):
+    def _exec(self, rql, args=None, rocheck=True):
         """json mode: execute RQL and return resultset as json"""
         if rocheck:
             self._cw.ensure_ro_rql(rql)
         try:
-            return self._cw.execute(rql, args, eidkey)
+            return self._cw.execute(rql, args)
         except Exception, ex:
             self.exception("error in _exec(rql=%s): %s", rql, ex)
             return None
--- a/web/views/bookmark.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/views/bookmark.py	Wed Apr 07 14:26:35 2010 +0200
@@ -112,7 +112,7 @@
                 else:
                     # we can't edit shared bookmarks we don't own
                     bookmarksrql = 'Bookmark B WHERE B bookmarked_by U, B owned_by U, U eid %(x)s'
-                    erset = req.execute(bookmarksrql, {'x': ueid}, 'x',
+                    erset = req.execute(bookmarksrql, {'x': ueid},
                                         build_descr=False)
                     bookmarksrql %= {'x': ueid}
                 if erset:
--- a/web/views/editcontroller.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/views/editcontroller.py	Wed Apr 07 14:26:35 2010 +0200
@@ -249,13 +249,13 @@
             rql = 'DELETE %s %s %s WHERE X eid %%(x)s, Y eid %%(y)s' % (
                 subjvar, rschema, objvar)
             for reid in origvalues.difference(values):
-                self.relations_rql.append((rql, {'x': eid, 'y': reid}, ('x', 'y')))
+                self.relations_rql.append((rql, {'x': eid, 'y': reid}))
         seteids = values.difference(origvalues)
         if seteids:
             rql = 'SET %s %s %s WHERE X eid %%(x)s, Y eid %%(y)s' % (
                 subjvar, rschema, objvar)
             for reid in seteids:
-                self.relations_rql.append((rql, {'x': eid, 'y': reid}, ('x', 'y')))
+                self.relations_rql.append((rql, {'x': eid, 'y': reid}))
 
     def delete_entities(self, eidtypes):
         """delete entities from the repository"""
--- a/web/views/urlpublishing.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/views/urlpublishing.py	Wed Apr 07 14:26:35 2010 +0200
@@ -130,8 +130,7 @@
         if len(parts) != 1:
             raise PathDontMatch()
         try:
-            rset = req.execute('Any X WHERE X eid %(x)s',
-                               {'x': typed_eid(parts[0])}, 'x')
+            rset = req.execute('Any X WHERE X eid %(x)s', {'x': typed_eid(parts[0])})
         except ValueError:
             raise PathDontMatch()
         if rset.rowcount == 0:
@@ -178,7 +177,7 @@
         rql = u'Any X WHERE X is %s, X %s %%(x)s' % (etype, attrname)
         if attrname == 'eid':
             try:
-                rset = req.execute(rql, {'x': typed_eid(value)}, 'x')
+                rset = req.execute(rql, {'x': typed_eid(value)})
             except (ValueError, TypeResolverException):
                 # conflicting eid/type
                 raise PathDontMatch()
--- a/web/views/workflow.py	Wed Apr 07 09:24:00 2010 +0200
+++ b/web/views/workflow.py	Wed Apr 07 14:26:35 2010 +0200
@@ -129,7 +129,7 @@
             headers = (_('from_state'), _('to_state'), _('comment'), _('date'))
         rql = '%s %s, X eid %%(x)s' % (sel, rql)
         try:
-            rset = self._cw.execute(rql, {'x': eid}, 'x')
+            rset = self._cw.execute(rql, {'x': eid})
         except Unauthorized:
             return
         if rset: