server/sources/rql2sql.py
changeset 5004 4cc020ee70e2
parent 4845 dc351b96f596
child 5016 b3b0b808a0ed
equal deleted inserted replaced
5003:cb27485ef5ae 5004:4cc020ee70e2
    71     """
    71     """
    72     torewrite = set()
    72     torewrite = set()
    73     modified = False
    73     modified = False
    74     for varname in tuple(unstable):
    74     for varname in tuple(unstable):
    75         var = select.defined_vars[varname]
    75         var = select.defined_vars[varname]
    76         if not var.stinfo['optrelations']:
    76         if not var.stinfo.get('optrelations'):
    77             continue
    77             continue
    78         modified = True
    78         modified = True
    79         unstable.remove(varname)
    79         unstable.remove(varname)
    80         torewrite.add(var)
    80         torewrite.add(var)
    81         newselect = Select()
    81         newselect = Select()
    98             newselect.add_restriction(newrel)
    98             newselect.add_restriction(newrel)
    99             select.remove_node(rel)
    99             select.remove_node(rel)
   100             var.stinfo['relations'].remove(rel)
   100             var.stinfo['relations'].remove(rel)
   101             newvar.stinfo['relations'].add(newrel)
   101             newvar.stinfo['relations'].add(newrel)
   102             if rel.optional in ('left', 'both'):
   102             if rel.optional in ('left', 'both'):
   103                 newvar.stinfo['optrelations'].add(newrel)
   103                 newvar.add_optional_relation(newrel)
   104             for vref in newrel.children[1].iget_nodes(VariableRef):
   104             for vref in newrel.children[1].iget_nodes(VariableRef):
   105                 var = vref.variable
   105                 var = vref.variable
   106                 var.stinfo['relations'].add(newrel)
   106                 var.stinfo['relations'].add(newrel)
   107                 var.stinfo['rhsrelations'].add(newrel)
   107                 var.stinfo['rhsrelations'].add(newrel)
   108                 if rel.optional in ('right', 'both'):
   108                 if rel.optional in ('right', 'both'):
   109                     var.stinfo['optrelations'].add(newrel)
   109                     var.add_optional_relation(newrel)
   110         # extract subquery solutions
   110         # extract subquery solutions
   111         mysolutions = [sol.copy() for sol in solutions]
   111         mysolutions = [sol.copy() for sol in solutions]
   112         cleanup_solutions(newselect, mysolutions)
   112         cleanup_solutions(newselect, mysolutions)
   113         newselect.set_possible_types(solutions)
   113         newselect.set_possible_types(solutions)
   114         # full sub-query
   114         # full sub-query
   814                     if rhsconst is not None:
   814                     if rhsconst is not None:
   815                         # inlined relation with invariant as rhs
   815                         # inlined relation with invariant as rhs
   816                         condition = '%s=%s' % (lhssql, rhsconst.accept(self))
   816                         condition = '%s=%s' % (lhssql, rhsconst.accept(self))
   817                         if relation.r_type != 'identity':
   817                         if relation.r_type != 'identity':
   818                             condition = '(%s OR %s IS NULL)' % (condition, lhssql)
   818                             condition = '(%s OR %s IS NULL)' % (condition, lhssql)
   819                         if not lhsvar.stinfo['optrelations']:
   819                         if not lhsvar.stinfo.get('optrelations'):
   820                             return condition
   820                             return condition
   821                         self.add_outer_join_condition(lhsvar, t1, condition)
   821                         self.add_outer_join_condition(lhsvar, t1, condition)
   822                     return
   822                     return
   823             else:
   823             else:
   824                 condition = '%s=%s' % (lhssql, rhsconst.accept(self))
   824                 condition = '%s=%s' % (lhssql, rhsconst.accept(self))
   907             #    sql = 'TIMESTAMP(%s)%s' % (lhssql, rhssql)
   907             #    sql = 'TIMESTAMP(%s)%s' % (lhssql, rhssql)
   908             else:
   908             else:
   909                 sql = '%s%s' % (lhssql, rhssql)
   909                 sql = '%s%s' % (lhssql, rhssql)
   910         except AttributeError:
   910         except AttributeError:
   911             sql = '%s%s' % (lhssql, rhssql)
   911             sql = '%s%s' % (lhssql, rhssql)
   912         if lhs.variable.stinfo['optrelations']:
   912         if lhs.variable.stinfo.get('optrelations'):
   913             self.add_outer_join_condition(lhs.variable, table, sql)
   913             self.add_outer_join_condition(lhs.variable, table, sql)
   914         else:
   914         else:
   915             return sql
   915             return sql
   916 
   916 
   917     def _visit_has_text_relation(self, rel):
   917     def _visit_has_text_relation(self, rel):
   922         jointo = lhs.accept(self)
   922         jointo = lhs.accept(self)
   923         restriction = ''
   923         restriction = ''
   924         lhsvar = lhs.variable
   924         lhsvar = lhs.variable
   925         me_is_principal = lhsvar.stinfo.get('principal') is rel
   925         me_is_principal = lhsvar.stinfo.get('principal') is rel
   926         if me_is_principal:
   926         if me_is_principal:
   927             if not lhsvar.stinfo['typerels']:
   927             if lhsvar.stinfo['typerel'] is None:
   928                 # the variable is using the fti table, no join needed
   928                 # the variable is using the fti table, no join needed
   929                 jointo = None
   929                 jointo = None
   930             elif not lhsvar.name in self._varmap:
   930             elif not lhsvar.name in self._varmap:
   931                 # join on entities instead of etype's table to get result for
   931                 # join on entities instead of etype's table to get result for
   932                 # external entities on multisources configurations
   932                 # external entities on multisources configurations
  1051             principal = variable.stinfo['principal']
  1051             principal = variable.stinfo['principal']
  1052             if principal is None:
  1052             if principal is None:
  1053                 vtablename = '_' + variable.name
  1053                 vtablename = '_' + variable.name
  1054                 self.add_table('entities AS %s' % vtablename, vtablename)
  1054                 self.add_table('entities AS %s' % vtablename, vtablename)
  1055                 sql = '%s.eid' % vtablename
  1055                 sql = '%s.eid' % vtablename
  1056                 if variable.stinfo['typerels']:
  1056                 if variable.stinfo['typerel'] is not None:
  1057                     # add additional restriction on entities.type column
  1057                     # add additional restriction on entities.type column
  1058                     pts = variable.stinfo['possibletypes']
  1058                     pts = variable.stinfo['possibletypes']
  1059                     if len(pts) == 1:
  1059                     if len(pts) == 1:
  1060                         etype = iter(variable.stinfo['possibletypes']).next()
  1060                         etype = iter(variable.stinfo['possibletypes']).next()
  1061                         restr = "%s.type='%s'" % (vtablename, etype)
  1061                         restr = "%s.type='%s'" % (vtablename, etype)
  1205     def add_outer_join_condition(self, var, table, condition):
  1205     def add_outer_join_condition(self, var, table, condition):
  1206         try:
  1206         try:
  1207             tablealias = self._state.outer_tables[table]
  1207             tablealias = self._state.outer_tables[table]
  1208             actualtables = self._state.actual_tables[-1]
  1208             actualtables = self._state.actual_tables[-1]
  1209         except KeyError:
  1209         except KeyError:
  1210             for rel in var.stinfo['optrelations']:
  1210             for rel in var.stinfo.get('optrelations'):
  1211                 self.visit_relation(rel)
  1211                 self.visit_relation(rel)
  1212             assert self._state.outer_tables
  1212             assert self._state.outer_tables
  1213             self.add_outer_join_condition(var, table, condition)
  1213             self.add_outer_join_condition(var, table, condition)
  1214             return
  1214             return
  1215         before, after = tablealias.split(' AS %s ' % table, 1)
  1215         before, after = tablealias.split(' AS %s ' % table, 1)