Skip to content

Commit 6c6fbb0

Browse files
committed
Pull the join logic into helper.
1 parent 2d213fb commit 6c6fbb0

1 file changed

Lines changed: 17 additions & 14 deletions

File tree

peewee.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9335,23 +9335,26 @@ def _parent_keys(parent_query, cols):
93359335
return sub
93369336

93379337

9338+
def _join_parent_keys(query, parent_query, pairs):
9339+
# The parent query can repeat a key (it may carry its own joins), and a
9340+
# duplicated key would multiply every row of query. Dedupe the keys
9341+
# rather than the query, which is bigger and may carry its own DISTINCT.
9342+
keys = list(dict.fromkeys([key for _, key in pairs]))
9343+
sub = _parent_keys(parent_query, keys).order_by().distinct()
9344+
on = reduce(operator.or_, [col == getattr(sub.c, key.column_name)
9345+
for col, key in pairs])
9346+
query = query.join(sub, on=on)
9347+
if len(pairs) > 1:
9348+
# Several fks OR'd together can match one row to two distinct keys,
9349+
# which deduping the keys cannot prevent.
9350+
query = query.distinct()
9351+
return query
9352+
9353+
93389354
def _relate(query, parent_query, pairs, strategy):
93399355
# Pairs are (column on query, the column it matches on parent_query).
93409356
if strategy == PREFETCH_TYPE.JOIN:
9341-
# Distinct the key subquery, not the child query. Deduping the
9342-
# keys prevents join fan-out without clobbering a child DISTINCT.
9343-
# Inherited ordering is dropped, a key set has none and postgres
9344-
# rejects DISTINCT ordered by an unprojected column.
9345-
keys = list(dict.fromkeys([key for _, key in pairs]))
9346-
sub = _parent_keys(parent_query, keys).order_by().distinct()
9347-
on = reduce(operator.or_, [col == getattr(sub.c, key.column_name)
9348-
for col, key in pairs])
9349-
query = query.join(sub, on=on)
9350-
if len(pairs) > 1:
9351-
# An OR join over several fks can match a child row to more
9352-
# than one key row, dedupe the children as well.
9353-
query = query.distinct()
9354-
return query
9357+
return _join_parent_keys(query, parent_query, pairs)
93559358
expr = reduce(operator.or_, [col << _parent_keys(parent_query, (key,))
93569359
for col, key in pairs])
93579360
return query.where(expr)

0 commit comments

Comments
 (0)