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) |