Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to do full outer join with django_cte #67

Open
jatinwatts opened this issue May 6, 2023 · 2 comments
Open

Not able to do full outer join with django_cte #67

jatinwatts opened this issue May 6, 2023 · 2 comments

Comments

@jatinwatts
Copy link

Django-cte is wonderful library. It has solved most my cases when comes to writing complex sql queries in django but recently i came across a situation where i had to do full outer join and i tired to do it with django_cte, i failed and when i debug the code in the library . i found it supports only inner and left outer join. So my point here is that can we add full outer join functionality in django_cte?? I assume my developers ran into this situation.

@jatinwatts
Copy link
Author

I think their will be change in the following function.

def join(self, join, reuse=None, reuse_with_filtered_relation=False):
    """
    Return an alias for the 'join', either reusing an existing alias for
    that join or creating a new one. 'join' is either a base_table_class or
    join_class.

    The 'reuse' parameter can be either None which means all joins are
    reusable, or it can be a set containing the aliases that can be reused.

    The 'reuse_with_filtered_relation' parameter is used when computing
    FilteredRelation instances.

    A join is always created as LOUTER if the lhs alias is LOUTER to make
    sure chains like t1 LOUTER t2 INNER t3 aren't generated. All new
    joins are created as LOUTER if the join is nullable.
    """
    if reuse_with_filtered_relation and reuse:
        reuse_aliases = [
            a for a, j in self.alias_map.items() if a in reuse and j.equals(join)
        ]
    else:
        reuse_aliases = [
            a
            for a, j in self.alias_map.items()
            if (reuse is None or a in reuse) and j == join
        ]
    if reuse_aliases:
        if join.table_alias in reuse_aliases:
            reuse_alias = join.table_alias
        else:
            # Reuse the most recent alias of the joined table
            # (a many-to-many relation may be joined multiple times).
            reuse_alias = reuse_aliases[-1]
        self.ref_alias(reuse_alias)
        return reuse_alias

    # No reuse is possible, so we need a new alias.
    alias, _ = self.table_alias(
        join.table_name, create=True, filtered_relation=join.filtered_relation
    )
    if join.join_type:
        if self.alias_map[join.parent_alias].join_type == LOUTER or join.nullable:
            join_type = LOUTER
        else:
            join_type = INNER
        join.join_type = join_type
    join.table_alias = alias
    self.alias_map[alias] = join
    return alias

@millerdev
Copy link
Contributor

Is that a code snippet from Django? If so, you'd need to take that up with the Django project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants