rqlrewrite.py
brancholdstable
changeset 5993 50e1a6ad3e98
parent 5704 924ea48326c4
child 5992 5f9a9086c171
equal deleted inserted replaced
5487:3ab2682a4b37 5993:50e1a6ad3e98
    52         try:
    52         try:
    53             var = newroot.defined_vars[varname]
    53             var = newroot.defined_vars[varname]
    54         except KeyError:
    54         except KeyError:
    55             continue
    55             continue
    56         stinfo = var.stinfo
    56         stinfo = var.stinfo
    57         if stinfo.get('uidrels'):
    57         if stinfo.get('uidrel') is not None:
    58             continue # eid specified, no need for additional type specification
    58             continue # eid specified, no need for additional type specification
    59         try:
    59         try:
    60             typerels = rqlst.defined_vars[varname].stinfo.get('typerels')
    60             typerel = rqlst.defined_vars[varname].stinfo.get('typerel')
    61         except KeyError:
    61         except KeyError:
    62             assert varname in rqlst.aliases
    62             assert varname in rqlst.aliases
    63             continue
    63             continue
    64         if newroot is rqlst and typerels:
    64         if newroot is rqlst and typerel is not None:
    65             mytyperel = iter(typerels).next()
    65             mytyperel = typerel
    66         else:
    66         else:
    67             for vref in newroot.defined_vars[varname].references():
    67             for vref in newroot.defined_vars[varname].references():
    68                 rel = vref.relation()
    68                 rel = vref.relation()
    69                 if rel and rel.is_types_restriction():
    69                 if rel and rel.is_types_restriction():
    70                     mytyperel = rel
    70                     mytyperel = rel
    91                 rel = var.scope.add_type_restriction(var, possibletypes)
    91                 rel = var.scope.add_type_restriction(var, possibletypes)
    92             else:
    92             else:
    93                 # tree is not annotated yet, no scope set so add the restriction
    93                 # tree is not annotated yet, no scope set so add the restriction
    94                 # to the root
    94                 # to the root
    95                 rel = newroot.add_type_restriction(var, possibletypes)
    95                 rel = newroot.add_type_restriction(var, possibletypes)
    96             stinfo['typerels'] = frozenset((rel,))
    96             stinfo['typerel'] = rel
    97             stinfo['possibletypes'] = possibletypes
    97             stinfo['possibletypes'] = possibletypes
    98 
    98 
    99 
    99 
   100 def remove_solutions(origsolutions, solutions, defined):
   100 def remove_solutions(origsolutions, solutions, defined):
   101     """when a rqlst has been generated from another by introducing security
   101     """when a rqlst has been generated from another by introducing security
   153     def rewrite(self, select, snippets, solutions, kwargs, existingvars=None):
   153     def rewrite(self, select, snippets, solutions, kwargs, existingvars=None):
   154         """
   154         """
   155         snippets: (varmap, list of rql expression)
   155         snippets: (varmap, list of rql expression)
   156                   with varmap a *tuple* (select var, snippet var)
   156                   with varmap a *tuple* (select var, snippet var)
   157         """
   157         """
   158         self.select = self.insert_scope = select
   158         self.select = select
   159         self.solutions = solutions
   159         self.solutions = solutions
   160         self.kwargs = kwargs
   160         self.kwargs = kwargs
   161         self.u_varname = None
   161         self.u_varname = None
   162         self.removing_ambiguity = False
   162         self.removing_ambiguity = False
   163         self.exists_snippet = {}
   163         self.exists_snippet = {}
   164         self.pending_keys = []
   164         self.pending_keys = []
   165         self.existingvars = existingvars
   165         self.existingvars = existingvars
       
   166         self._insert_scope = None
   166         # we have to annotate the rqlst before inserting snippets, even though
   167         # we have to annotate the rqlst before inserting snippets, even though
   167         # we'll have to redo it latter
   168         # we'll have to redo it latter
   168         self.annotate(select)
   169         self.annotate(select)
   169         self.insert_snippets(snippets)
   170         self.insert_snippets(snippets)
   170         if not self.exists_snippet and self.u_varname:
   171         if not self.exists_snippet and self.u_varname:
   247         finally:
   248         finally:
   248             self.existingvars = existing
   249             self.existingvars = existing
   249 
   250 
   250     def _insert_snippet(self, varmap, parent, new):
   251     def _insert_snippet(self, varmap, parent, new):
   251         if new is not None:
   252         if new is not None:
       
   253             if self._insert_scope is None:
       
   254                 insert_scope = self.varinfo.get('stinfo', {}).get('scope', self.select)
       
   255             else:
       
   256                 insert_scope = self._insert_scope
   252             if self.varinfo.get('stinfo', {}).get('optrelations'):
   257             if self.varinfo.get('stinfo', {}).get('optrelations'):
   253                 assert parent is None
   258                 assert parent is None
   254                 self.insert_scope = self.snippet_subquery(varmap, new)
   259                 self._insert_scope = self.snippet_subquery(varmap, new)
   255                 self.insert_pending()
   260                 self.insert_pending()
   256                 self.insert_scope = self.select
   261                 self._insert_scope = None
   257                 return
   262                 return
   258             new = n.Exists(new)
   263             new = n.Exists(new)
   259             if parent is None:
   264             if parent is None:
   260                 self.insert_scope.add_restriction(new)
   265                 insert_scope.add_restriction(new)
   261             else:
   266             else:
   262                 grandpa = parent.parent
   267                 grandpa = parent.parent
   263                 or_ = n.Or(parent, new)
   268                 or_ = n.Or(parent, new)
   264                 grandpa.replace(parent, or_)
   269                 grandpa.replace(parent, or_)
   265             if not self.removing_ambiguity:
   270             if not self.removing_ambiguity:
   272                     else:
   277                     else:
   273                         parent.parent.replace(or_, or_.children[0])
   278                         parent.parent.replace(or_, or_.children[0])
   274                         self._cleanup_inserted(new)
   279                         self._cleanup_inserted(new)
   275                     raise
   280                     raise
   276                 else:
   281                 else:
   277                     self.insert_scope = new
   282                     self._insert_scope = new
   278                     self.insert_pending()
   283                     self.insert_pending()
   279                     self.insert_scope = self.select
   284                     self._insert_scope = None
   280             return new
   285             return new
   281         self.insert_pending()
   286         self.insert_pending()
   282 
   287 
   283     def insert_pending(self):
   288     def insert_pending(self):
   284         """pending_keys hold variable referenced by U has_<action>_permission X
   289         """pending_keys hold variable referenced by U has_<action>_permission X
   346                 if rschema.inlined and rel.optional:
   351                 if rschema.inlined and rel.optional:
   347                     need_null_test = True
   352                     need_null_test = True
   348         if need_null_test:
   353         if need_null_test:
   349             snippetrqlst = n.Or(
   354             snippetrqlst = n.Or(
   350                 n.make_relation(subselectvar, 'is', (None, None), n.Constant,
   355                 n.make_relation(subselectvar, 'is', (None, None), n.Constant,
   351                                 operator='IS'),
   356                                 operator='='),
   352                 snippetrqlst)
   357                 snippetrqlst)
   353         subselect.add_restriction(snippetrqlst)
   358         subselect.add_restriction(snippetrqlst)
   354         if self.u_varname:
   359         if self.u_varname:
   355             # generate an identifier for the substitution
   360             # generate an identifier for the substitution
   356             argname = subselect.allocate_varname()
   361             argname = subselect.allocate_varname()