MCPcopy
hub / github.com/django/django / bump_prefix

Method bump_prefix

django/db/models/sql/query.py:1057–1110  ·  view source on GitHub ↗

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 para

(self, other_query, exclude=None)

Source from the content-addressed store, hash-verified

1055 combined_query.change_aliases(external_change_map)
1056
1057 def bump_prefix(self, other_query, exclude=None):
1058 """
1059 Change the alias prefix to the next letter in the alphabet in a way
1060 that the other query's aliases and this query's aliases will not
1061 conflict. Even tables that previously had no alias will get an alias
1062 after this call. To prevent changing aliases use the exclude parameter.
1063 """
1064
1065 def prefix_gen():
1066 """
1067 Generate a sequence of characters in alphabetical order:
1068 -> 'A', 'B', 'C', ...
1069
1070 When the alphabet is finished, the sequence will continue with the
1071 Cartesian product:
1072 -> 'AA', 'AB', 'AC', ...
1073 """
1074 alphabet = ascii_uppercase
1075 prefix = chr(ord(self.alias_prefix) + 1)
1076 yield prefix
1077 for n in count(1):
1078 seq = alphabet[alphabet.index(prefix) :] if prefix else alphabet
1079 for s in product(seq, repeat=n):
1080 yield "".join(s)
1081 prefix = None
1082
1083 if self.alias_prefix != other_query.alias_prefix:
1084 # No clashes between self and outer query should be possible.
1085 return
1086
1087 # Explicitly avoid infinite loop. The constant divider is based on how
1088 # much depth recursive subquery references add to the stack. This value
1089 # might need to be adjusted when adding or removing function calls from
1090 # the code path in charge of performing these operations.
1091 local_recursion_limit = sys.getrecursionlimit() // 16
1092 for pos, prefix in enumerate(prefix_gen()):
1093 if prefix not in self.subq_aliases:
1094 self.alias_prefix = prefix
1095 break
1096 if pos > local_recursion_limit:
1097 raise RecursionError(
1098 "Maximum recursion depth exceeded: too many subqueries."
1099 )
1100 self.subq_aliases = self.subq_aliases.union([self.alias_prefix])
1101 other_query.subq_aliases = other_query.subq_aliases.union(self.subq_aliases)
1102 if exclude is None:
1103 exclude = {}
1104 self.change_aliases(
1105 {
1106 alias: "%s%d" % (self.alias_prefix, pos)
1107 for pos, alias in enumerate(self.alias_map)
1108 if alias not in exclude
1109 }
1110 )
1111
1112 def get_initial_alias(self):
1113 """

Callers 3

combineMethod · 0.80
resolve_expressionMethod · 0.80
split_excludeMethod · 0.80

Calls 2

change_aliasesMethod · 0.95
unionMethod · 0.45

Tested by

no test coverage detected