server/ssplanner.py
changeset 4795 f1c8bc628b45
parent 4764 ec9c20c6b9f7
child 4835 13b0b96d7982
equal deleted inserted replaced
4793:fdb5476dee9a 4795:f1c8bc628b45
    74                 if eid not in neweids:
    74                 if eid not in neweids:
    75                     eschema(session.describe(eid)[0]).check_perm(session, 'read')
    75                     eschema(session.describe(eid)[0]).check_perm(session, 'read')
    76                 eidconsts[lhs.variable] = eid
    76                 eidconsts[lhs.variable] = eid
    77     return eidconsts
    77     return eidconsts
    78 
    78 
       
    79 def _build_substep_query(select, origrqlst):
       
    80     """Finalize substep select query that should be executed to get proper
       
    81     selection of stuff to insert/update.
       
    82 
       
    83     Return None when no query actually needed, else the given select node that
       
    84     will be used as substep query.
       
    85 
       
    86     When select has nothing selected, search in origrqlst for restriction that
       
    87     should be considered.
       
    88     """
       
    89     if select.selection:
       
    90         if origrqlst.where is not None:
       
    91             select.set_where(origrqlst.where.copy(select))
       
    92         return select
       
    93     if origrqlst.where is None:
       
    94         return
       
    95     for rel in origrqlst.where.iget_nodes(Relation):
       
    96         # search for a relation which is neither a type restriction (is) nor an
       
    97         # eid specification (not neged eid with constant node
       
    98         if rel.neged(strict=True) or not (
       
    99             rel.is_types_restriction() or
       
   100             (rel.r_type == 'eid'
       
   101              and isinstance(rel.get_variable_parts()[1], Constant))):
       
   102             break
       
   103     else:
       
   104         return
       
   105     select.set_where(origrqlst.where.copy(select))
       
   106     if not select.selection:
       
   107         # no selection, append one randomly
       
   108         select.append_selected(rel.children[0].copy(select))
       
   109     return select
       
   110 
    79 
   111 
    80 class SSPlanner(object):
   112 class SSPlanner(object):
    81     """SingleSourcePlanner: build execution plan for rql queries
   113     """SingleSourcePlanner: build execution plan for rql queries
    82 
   114 
    83     optimized for single source repositories
   115     optimized for single source repositories
   142                     if rschema.final or rschema.inlined:
   174                     if rschema.final or rschema.inlined:
   143                         rdefs[i] = (rtype, InsertRelationsStep.FINAL, value)
   175                         rdefs[i] = (rtype, InsertRelationsStep.FINAL, value)
   144                     else:
   176                     else:
   145                         rdefs[i] = (rtype, InsertRelationsStep.RELATION, value)
   177                         rdefs[i] = (rtype, InsertRelationsStep.RELATION, value)
   146             step = InsertRelationsStep(plan, edef, rdefs)
   178             step = InsertRelationsStep(plan, edef, rdefs)
   147             if select.selection:
   179             select = _build_substep_query(select, rqlst)
   148                 if rqlst.where is not None:
   180             if select is not None:
   149                     select.set_where(rqlst.where.copy(select))
       
   150                 step.children += self._select_plan(plan, select, rqlst.solutions)
   181                 step.children += self._select_plan(plan, select, rqlst.solutions)
   151             yield step
   182             yield step
   152 
   183 
   153     def build_delete_plan(self, plan, rqlst):
   184     def build_delete_plan(self, plan, rqlst):
   154         """get an execution plan from a DELETE RQL query"""
   185         """get an execution plan from a DELETE RQL query"""
   239             if rschema.final or rschema.inlined:
   270             if rschema.final or rschema.inlined:
   240                 attributes.add(relation.r_type)
   271                 attributes.add(relation.r_type)
   241         # the update step
   272         # the update step
   242         step = UpdateStep(plan, updatedefs, attributes)
   273         step = UpdateStep(plan, updatedefs, attributes)
   243         # when necessary add substep to fetch yet unknown values
   274         # when necessary add substep to fetch yet unknown values
   244         if select.selection:
   275         select = _build_substep_query(select, rqlst)
   245             if rqlst.where is not None:
   276         if select is not None:
   246                 select.set_where(rqlst.where.copy(select))
       
   247             # set distinct to avoid potential duplicate key error
   277             # set distinct to avoid potential duplicate key error
   248             select.distinct = True
   278             select.distinct = True
   249             step.children += self._select_plan(plan, select, rqlst.solutions)
   279             step.children += self._select_plan(plan, select, rqlst.solutions)
   250         return (step,)
   280         return (step,)
   251 
   281