server/querier.py
branch3.5
changeset 3240 8604a15995d1
parent 3171 b10f0c1f3fe4
child 3689 deb13e88e037
equal deleted inserted replaced
3239:1ceac4cd4fb7 3240:8604a15995d1
   136         # index of temporary tables created during execution
   136         # index of temporary tables created during execution
   137         self.temp_tables = {}
   137         self.temp_tables = {}
   138         # various resource accesors
   138         # various resource accesors
   139         self.querier = querier
   139         self.querier = querier
   140         self.schema = querier.schema
   140         self.schema = querier.schema
   141         self.rqlhelper = querier._rqlhelper
       
   142         self.sqlannotate = querier.sqlgen_annotate
   141         self.sqlannotate = querier.sqlgen_annotate
       
   142         self.rqlhelper = session.vreg.rqlhelper
   143 
   143 
   144     def annotate_rqlst(self):
   144     def annotate_rqlst(self):
   145         if not self.rqlst.annotated:
   145         if not self.rqlst.annotated:
   146             self.rqlhelper.annotate(self.rqlst)
   146             self.rqlhelper.annotate(self.rqlst)
   147 
   147 
   263                     if not lcheckdef:
   263                     if not lcheckdef:
   264                         continue
   264                         continue
   265                     myrqlst = select.copy(solutions=lchecksolutions)
   265                     myrqlst = select.copy(solutions=lchecksolutions)
   266                     myunion.append(myrqlst)
   266                     myunion.append(myrqlst)
   267                     # in-place rewrite + annotation / simplification
   267                     # in-place rewrite + annotation / simplification
       
   268                     lcheckdef = [((varmap, 'X'), rqlexprs)
       
   269                                  for varmap, rqlexprs in lcheckdef]
   268                     rewrite(myrqlst, lcheckdef, lchecksolutions, self.args)
   270                     rewrite(myrqlst, lcheckdef, lchecksolutions, self.args)
   269                     noinvariant.update(noinvariant_vars(restricted, myrqlst, nbtrees))
   271                     noinvariant.update(noinvariant_vars(restricted, myrqlst, nbtrees))
   270                 if () in localchecks:
   272                 if () in localchecks:
   271                     select.set_possible_types(localchecks[()])
   273                     select.set_possible_types(localchecks[()])
   272                     add_types_restriction(self.schema, select)
   274                     add_types_restriction(self.schema, select)
   522         # instance schema
   524         # instance schema
   523         self.set_schema(schema)
   525         self.set_schema(schema)
   524 
   526 
   525     def set_schema(self, schema):
   527     def set_schema(self, schema):
   526         self.schema = schema
   528         self.schema = schema
       
   529         repo = self._repo
   527         # rql parsing / analysing helper
   530         # rql parsing / analysing helper
   528         self._rqlhelper = RQLHelper(schema, special_relations={'eid': 'uid',
   531         self.solutions = repo.vreg.solutions
   529                                                                'has_text': 'fti'})
   532         self._rql_cache = Cache(repo.config['rql-cache-size'])
   530         self._rql_cache = Cache(self._repo.config['rql-cache-size'])
       
   531         self.cache_hit, self.cache_miss = 0, 0
   533         self.cache_hit, self.cache_miss = 0, 0
   532         # rql planner
   534         # rql planner
   533         # note: don't use repo.sources, may not be built yet, and also "admin"
   535         # note: don't use repo.sources, may not be built yet, and also "admin"
   534         #       isn't an actual source
   536         #       isn't an actual source
   535         if len([uri for uri in self._repo.config.sources() if uri != 'admin']) < 2:
   537         rqlhelper = repo.vreg.rqlhelper
       
   538         self._parse = rqlhelper.parse
       
   539         self._annotate = rqlhelper.annotate
       
   540         if len([uri for uri in repo.config.sources() if uri != 'admin']) < 2:
   536             from cubicweb.server.ssplanner import SSPlanner
   541             from cubicweb.server.ssplanner import SSPlanner
   537             self._planner = SSPlanner(schema, self._rqlhelper)
   542             self._planner = SSPlanner(schema, rqlhelper)
   538         else:
   543         else:
   539             from cubicweb.server.msplanner import MSPlanner
   544             from cubicweb.server.msplanner import MSPlanner
   540             self._planner = MSPlanner(schema, self._rqlhelper)
   545             self._planner = MSPlanner(schema, rqlhelper)
   541         # sql generation annotator
   546         # sql generation annotator
   542         self.sqlgen_annotate = SQLGenAnnotator(schema).annotate
   547         self.sqlgen_annotate = SQLGenAnnotator(schema).annotate
   543 
   548 
   544     def parse(self, rql, annotate=False):
   549     def parse(self, rql, annotate=False):
   545         """return a rql syntax tree for the given rql"""
   550         """return a rql syntax tree for the given rql"""
   546         try:
   551         try:
   547             return self._rqlhelper.parse(unicode(rql), annotate=annotate)
   552             return self._parse(unicode(rql), annotate=annotate)
   548         except UnicodeError:
   553         except UnicodeError:
   549             raise RQLSyntaxError(rql)
   554             raise RQLSyntaxError(rql)
   550 
       
   551     def solutions(self, session, rqlst, args):
       
   552         assert session is not None
       
   553         def type_from_eid(eid, type_from_eid=self._repo.type_from_eid,
       
   554                           session=session):
       
   555             return type_from_eid(eid, session)
       
   556         self._rqlhelper.compute_solutions(rqlst, {'eid': type_from_eid}, args)
       
   557 
   555 
   558     def plan_factory(self, rqlst, args, session):
   556     def plan_factory(self, rqlst, args, session):
   559         """create an execution plan for an INSERT RQL query"""
   557         """create an execution plan for an INSERT RQL query"""
   560         if rqlst.TYPE == 'insert':
   558         if rqlst.TYPE == 'insert':
   561             return InsertPlan(self, rqlst, args, session)
   559             return InsertPlan(self, rqlst, args, session)
   640                     check_no_password_selected(select)
   638                     check_no_password_selected(select)
   641             # on select query, always copy the cached rqlst so we don't have to
   639             # on select query, always copy the cached rqlst so we don't have to
   642             # bother modifying it. This is not necessary on write queries since
   640             # bother modifying it. This is not necessary on write queries since
   643             # a new syntax tree is built from them.
   641             # a new syntax tree is built from them.
   644             rqlst = rqlst.copy()
   642             rqlst = rqlst.copy()
   645             self._rqlhelper.annotate(rqlst)
   643             self._annotate(rqlst)
   646         # make an execution plan
   644         # make an execution plan
   647         plan = self.plan_factory(rqlst, args, session)
   645         plan = self.plan_factory(rqlst, args, session)
   648         plan.cache_key = cachekey
   646         plan.cache_key = cachekey
   649         self._planner.build_plan(plan)
   647         self._planner.build_plan(plan)
   650         # execute the plan
   648         # execute the plan