diff -r 432e1f0d4857 -r 59fea81647e5 server/sources/rql2sql.py --- 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):