Repository: django/django
File: django/db/models/sql/query.py (Python)

Code before:
            self.group_by = tuple(
                [col.relabeled_clone(change_map) for col in self.group_by]
            )
        self.select = tuple([col.relabeled_clone(change_map) for col in self.select])
        self.annotations = self.annotations and {
            key: col.relabeled_clone(change_map)
            for key, col in self.annotations.items()
        }

        # 2. Rename the alias in the internal table/alias datastructures.
        for old_alias, new_alias in change_map.items():
            if old_alias not in self.alias_map:
                continue
            alias_data = self.alias_map[old_alias].relabeled_clone(change_map)
            self.alias_map[new_alias] = alias_data
            self.alias_refcount[new_alias] = self.alias_refcount[old_alias]
            del self.alias_refcount[old_alias]
            del self.alias_map[old_alias]

            table_aliases = self.table_map[alias_data.table_name]
            for pos, alias in enumerate(table_aliases):
                if alias == old_alias:
                    table_aliases[pos] = new_alias
                    break
        self.external_aliases = {
            # Table is aliased or it's being changed and thus is aliased.
            change_map.get(alias, alias): (aliased or alias in change_map)
            for alias, aliased in self.external_aliases.items()
        }

    def bump_prefix(self, other_query, exclude=None):
        """
        Change the alias prefix to the next letter in the alphabet in a way
        that the other query's aliases and this query's aliases will not
        conflict. Even tables that previously had no alias will get an alias
        after this call. To prevent changing aliases use the exclude parameter.
        """

        def prefix_gen():
            """
            Generate a sequence of characters in alphabetical order:
                -> 'A', 'B', 'C', ...

            When the alphabet is finished, the sequence will continue with the
            Cartesian product:
                -> 'AA', 'AB', 'AC', ...
            """
            alphabet = ascii_uppercase
            prefix = chr(ord(self.alias_prefix) + 1)
            yield prefix
            for n in count(1):

Review comment (suggestion):
I guess the comment here could be adjusted to mention that we're doing that both for direct and combined queries external aliases.

Code after:
            self.group_by = tuple(
                [col.relabeled_clone(change_map) for col in self.group_by]
            )
        self.select = tuple([col.relabeled_clone(change_map) for col in self.select])
        self.annotations = self.annotations and {
            key: col.relabeled_clone(change_map)
            for key, col in self.annotations.items()
        }

        # 2. Rename the alias in the internal table/alias datastructures.
        for old_alias, new_alias in change_map.items():
            if old_alias not in self.alias_map:
                continue
            alias_data = self.alias_map[old_alias].relabeled_clone(change_map)
            self.alias_map[new_alias] = alias_data
            self.alias_refcount[new_alias] = self.alias_refcount[old_alias]
            del self.alias_refcount[old_alias]
            del self.alias_map[old_alias]

            table_aliases = self.table_map[alias_data.table_name]
            for pos, alias in enumerate(table_aliases):
                if alias == old_alias:
                    table_aliases[pos] = new_alias
                    break

        # 3. Rename the direct external aliases and the ones of combined
        # queries (union, intersection, difference).
        self.external_aliases = {
            # Table is aliased or it's being changed and thus is aliased.
            change_map.get(alias, alias): (aliased or alias in change_map)
            for alias, aliased in self.external_aliases.items()
        }
        for combined_query in self.combined_queries:
            external_change_map = {
                alias: aliased
                for alias, aliased in change_map.items()
                if alias in combined_query.external_aliases
            }
            combined_query.change_aliases(external_change_map)

    def bump_prefix(self, other_query, exclude=None):
        """
        Change the alias prefix to the next letter in the alphabet in a way
        that the other query's aliases and this query's aliases will not
        conflict. Even tables that previously had no alias will get an alias
        after this call. To prevent changing aliases use the exclude parameter.
        """

        def prefix_gen():
            """
            Generate a sequence of characters in alphabetical order: