server/sources/rql2sql.py
branchstable
changeset 7734 59fea81647e5
parent 7729 5f89f11143bc
child 7902 2ada3052e626
--- a/server/sources/rql2sql.py	Wed Aug 03 13:28:06 2011 +0200
+++ b/server/sources/rql2sql.py	Thu Aug 04 12:50:48 2011 +0200
@@ -1238,35 +1238,47 @@
 
 
     def _visit_outer_join_inlined_relation(self, relation, rschema):
-        leftvar, leftconst, rightvar, rightconst = relation_info(relation)
-        assert not (leftconst and rightconst), "doesn't make sense"
-        if relation.optional != 'right':
-            leftvar, rightvar = rightvar, leftvar
-            leftconst, rightconst = rightconst, leftconst
-        outertype = 'FULL' if relation.optional == 'both' else 'LEFT'
-        leftalias = self._var_table(leftvar)
+        lhsvar, lhsconst, rhsvar, rhsconst = relation_info(relation)
+        assert not (lhsconst and rhsconst), "doesn't make sense"
         attr = 'eid' if relation.r_type == 'identity' else relation.r_type
-        lhs, rhs = relation.get_variable_parts()
+        lhsalias = self._var_table(lhsvar)
+        rhsalias = rhsvar and self._var_table(rhsvar)
         try:
-            lhssql = self._varmap['%s.%s' % (lhs.name, attr)]
+            lhssql = self._varmap['%s.%s' % (lhsvar.name, attr)]
         except KeyError:
-            lhssql = '%s.%s%s' % (self._var_table(lhs.variable), SQL_PREFIX, attr)
-        if rightvar is not None:
-            rightalias = self._var_table(rightvar)
-            if rightalias is None:
-                if rightconst is not None:
-                    # inlined relation with invariant as rhs
-                    condition = '%s=%s' % (lhssql, rightconst.accept(self))
-                    if relation.r_type != 'identity':
-                        condition = '(%s OR %s IS NULL)' % (condition, lhssql)
-                    if not leftvar.stinfo.get('optrelations'):
-                        return condition
-                    self._state.add_outer_join_condition(leftalias, condition)
-                return
-        if leftalias is None:
-            leftalias = leftvar._q_sql.split('.', 1)[0]
-        self._state.replace_tables_by_outer_join(
-            leftalias, rightalias, outertype, '%s=%s' % (lhssql, rhs.accept(self)))
+            if lhsalias is None:
+                lhssql = lhsconst.accept(self)
+            else:
+                lhssql = '%s.%s%s' % (lhsalias, SQL_PREFIX, attr)
+        condition = '%s=%s' % (lhssql, (rhsconst or rhsvar).accept(self))
+        # this is not a typo, rhs optional variable means lhs outer join and vice-versa
+        if relation.optional == 'left':
+            lhsvar, rhsvar = rhsvar, lhsvar
+            lhsconst, rhsconst = rhsconst, lhsconst
+            lhsalias, rhsalias = rhsalias, lhsalias
+            outertype = 'LEFT'
+        elif relation.optional == 'both':
+            outertype = 'FULL'
+        else:
+            outertype = 'LEFT'
+        if rhsalias is None:
+            if rhsconst is not None:
+                # inlined relation with invariant as rhs
+                if relation.r_type != 'identity':
+                    condition = '(%s OR %s IS NULL)' % (condition, lhssql)
+                if not lhsvar.stinfo.get('optrelations'):
+                    return condition
+                self._state.add_outer_join_condition(lhsalias, condition)
+            return
+        if lhsalias is None:
+            if lhsconst is not None and not rhsvar.stinfo.get('optrelations'):
+                return condition
+            lhsalias = lhsvar._q_sql.split('.', 1)[0]
+        if lhsalias == rhsalias:
+            self._state.add_outer_join_condition(lhsalias, condition)
+        else:
+            self._state.replace_tables_by_outer_join(
+                lhsalias, rhsalias, outertype, condition)
         return ''
 
     def _visit_var_attr_relation(self, relation, rhs_vars):