cubicweb/server/querier.py
changeset 12931 6eae252361e5
parent 12889 bbf3e56b43fe
equal deleted inserted replaced
12930:665f66e57fc6 12931:6eae252361e5
    23 import traceback
    23 import traceback
    24 from itertools import repeat
    24 from itertools import repeat
    25 
    25 
    26 from rql import RQLSyntaxError, CoercionError
    26 from rql import RQLSyntaxError, CoercionError
    27 from rql.stmts import Union
    27 from rql.stmts import Union
    28 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
    28 from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not,\
       
    29     VariableRef, Constant
    29 from yams import BASE_TYPES
    30 from yams import BASE_TYPES
    30 
    31 
    31 from cubicweb import ValidationError, Unauthorized, UnknownEid, QueryError
    32 from cubicweb import ValidationError, Unauthorized, UnknownEid, QueryError
    32 from cubicweb.rqlrewrite import RQLRelationRewriter
    33 from cubicweb.rqlrewrite import RQLRelationRewriter
    33 from cubicweb import Binary, server
    34 from cubicweb import Binary, server
   577         query_debug_informations["time"] = ((time.time() - start) * 1000)
   578         query_debug_informations["time"] = ((time.time() - start) * 1000)
   578         query_debug_informations["result"] = results
   579         query_debug_informations["result"] = results
   579 
   580 
   580         # build a description for the results if necessary
   581         # build a description for the results if necessary
   581         descr = ()
   582         descr = ()
       
   583         variables = None
   582         if build_descr:
   584         if build_descr:
   583             if rqlst.TYPE == 'select':
   585             if rqlst.TYPE == 'select':
   584                 # sample selection
   586                 # sample selection
   585                 if len(rqlst.children) == 1 and len(rqlst.children[0].solutions) == 1:
   587                 if len(rqlst.children) == 1 and len(rqlst.children[0].solutions) == 1:
   586                     # easy, all lines are identical
   588                     # easy, all lines are identical
   587                     selected = rqlst.children[0].selection
   589                     selected = rqlst.children[0].selection
   588                     solution = rqlst.children[0].solutions[0]
   590                     solution = rqlst.children[0].solutions[0]
   589                     description = _make_description(selected, args, solution)
   591                     description = _make_description(selected, args, solution)
   590                     descr = RepeatList(len(results), tuple(description))
   592                     descr = RepeatList(len(results), tuple(description))
       
   593                     variables = [self._get_projected_name(projected, rqlst.children[0].stinfo)
       
   594                                  for projected in selected]
   591                 else:
   595                 else:
   592                     # hard, delegate the work :o)
   596                     # hard, delegate the work :o)
   593                     descr = manual_build_descr(cnx, rqlst, args, results)
   597                     descr = manual_build_descr(cnx, rqlst, args, results)
   594             elif rqlst.TYPE == 'insert':
   598             elif rqlst.TYPE == 'insert':
   595                 # on insert plan, some entities may have been auto-casted,
   599                 # on insert plan, some entities may have been auto-casted,
   603             query_debug_informations["description"] = descr
   607             query_debug_informations["description"] = descr
   604 
   608 
   605         emit_to_debug_channel("rql", query_debug_informations)
   609         emit_to_debug_channel("rql", query_debug_informations)
   606 
   610 
   607         # return a result set object
   611         # return a result set object
   608         return ResultSet(results, rql, args, descr)
   612         return ResultSet(results, rql, args, descr, variables)
   609 
   613 
   610     # these are overridden by set_log_methods below
   614     # these are overridden by set_log_methods below
   611     # only defining here to prevent pylint from complaining
   615     # only defining here to prevent pylint from complaining
   612     info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
   616     info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
       
   617 
       
   618     @staticmethod
       
   619     def _get_projected_name(projected, stinfo):
       
   620         if isinstance(projected, VariableRef):
       
   621             return projected.name
       
   622         elif isinstance(projected, Constant):
       
   623             if stinfo['rewritten'] is None:
       
   624                 return str(projected)
       
   625             for name, value in stinfo['rewritten'].items():
       
   626                 if [projected] == value:
       
   627                     return name
       
   628         return str(projected)
   613 
   629 
   614 
   630 
   615 class RQLCache(object):
   631 class RQLCache(object):
   616 
   632 
   617     def __init__(self, repo, schema):
   633     def __init__(self, repo, schema):