66from django .db .models .constants import LOOKUP_SEP
77from django .db .models .query_utils import select_related_descend
88from django .db .models .sql .constants import (SINGLE , MULTI , ORDER_DIR ,
9- GET_ITERATOR_CHUNK_SIZE , SelectInfo )
9+ GET_ITERATOR_CHUNK_SIZE , REUSE_ALL , SelectInfo )
1010from django .db .models .sql .datastructures import EmptyResultSet
1111from django .db .models .sql .expressions import SQLEvaluator
1212from django .db .models .sql .query import get_order_dir , Query
@@ -457,7 +457,7 @@ def _setup_joins(self, pieces, opts, alias):
457457 if not alias :
458458 alias = self .query .get_initial_alias ()
459459 field , target , opts , joins , _ , _ = self .query .setup_joins (pieces ,
460- opts , alias , False )
460+ opts , alias , REUSE_ALL )
461461 # We will later on need to promote those joins that were added to the
462462 # query afresh above.
463463 joins_to_promote = [j for j in joins if self .query .alias_refcount [j ] < 2 ]
@@ -574,8 +574,7 @@ def get_grouping(self):
574574 return result , params
575575
576576 def fill_related_selections (self , opts = None , root_alias = None , cur_depth = 1 ,
577- used = None , requested = None , restricted = None , nullable = None ,
578- dupe_set = None , avoid_set = None ):
577+ requested = None , restricted = None , nullable = None ):
579578 """
580579 Fill in the information needed for a select_related query. The current
581580 depth is measured as the number of connections away from the root model
@@ -590,13 +589,6 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
590589 opts = self .query .get_meta ()
591590 root_alias = self .query .get_initial_alias ()
592591 self .query .related_select_cols = []
593- if not used :
594- used = set ()
595- if dupe_set is None :
596- dupe_set = set ()
597- if avoid_set is None :
598- avoid_set = set ()
599- orig_dupe_set = dupe_set
600592 only_load = self .query .get_loaded_field_names ()
601593
602594 # Setup for the case when only particular related fields should be
@@ -616,12 +608,6 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
616608 if not select_related_descend (f , restricted , requested ,
617609 only_load .get (field_model )):
618610 continue
619- # The "avoid" set is aliases we want to avoid just for this
620- # particular branch of the recursion. They aren't permanently
621- # forbidden from reuse in the related selection tables (which is
622- # what "used" specifies).
623- avoid = avoid_set .copy ()
624- dupe_set = orig_dupe_set .copy ()
625611 table = f .rel .to ._meta .db_table
626612 promote = nullable or f .null
627613 if model :
@@ -637,31 +623,17 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
637623 int_opts = int_model ._meta
638624 continue
639625 lhs_col = int_opts .parents [int_model ].column
640- dedupe = lhs_col in opts .duplicate_targets
641- if dedupe :
642- avoid .update (self .query .dupe_avoidance .get ((id (opts ), lhs_col ),
643- ()))
644- dupe_set .add ((opts , lhs_col ))
645626 int_opts = int_model ._meta
646627 alias = self .query .join ((alias , int_opts .db_table , lhs_col ,
647- int_opts .pk .column ), exclusions = used ,
628+ int_opts .pk .column ),
648629 promote = promote )
649630 alias_chain .append (alias )
650- for (dupe_opts , dupe_col ) in dupe_set :
651- self .query .update_dupe_avoidance (dupe_opts , dupe_col , alias )
652631 else :
653632 alias = root_alias
654633
655- dedupe = f .column in opts .duplicate_targets
656- if dupe_set or dedupe :
657- avoid .update (self .query .dupe_avoidance .get ((id (opts ), f .column ), ()))
658- if dedupe :
659- dupe_set .add ((opts , f .column ))
660-
661634 alias = self .query .join ((alias , table , f .column ,
662635 f .rel .get_related_field ().column ),
663- exclusions = used .union (avoid ), promote = promote )
664- used .add (alias )
636+ promote = promote )
665637 columns , aliases = self .get_default_columns (start_alias = alias ,
666638 opts = f .rel .to ._meta , as_pairs = True )
667639 self .query .related_select_cols .extend (
@@ -671,10 +643,8 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
671643 else :
672644 next = False
673645 new_nullable = f .null or promote
674- for dupe_opts , dupe_col in dupe_set :
675- self .query .update_dupe_avoidance (dupe_opts , dupe_col , alias )
676646 self .fill_related_selections (f .rel .to ._meta , alias , cur_depth + 1 ,
677- used , next , restricted , new_nullable , dupe_set , avoid )
647+ next , restricted , new_nullable )
678648
679649 if restricted :
680650 related_fields = [
@@ -686,14 +656,8 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
686656 if not select_related_descend (f , restricted , requested ,
687657 only_load .get (model ), reverse = True ):
688658 continue
689- # The "avoid" set is aliases we want to avoid just for this
690- # particular branch of the recursion. They aren't permanently
691- # forbidden from reuse in the related selection tables (which is
692- # what "used" specifies).
693- avoid = avoid_set .copy ()
694- dupe_set = orig_dupe_set .copy ()
695- table = model ._meta .db_table
696659
660+ table = model ._meta .db_table
697661 int_opts = opts
698662 alias = root_alias
699663 alias_chain = []
@@ -708,30 +672,16 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
708672 int_opts = int_model ._meta
709673 continue
710674 lhs_col = int_opts .parents [int_model ].column
711- dedupe = lhs_col in opts .duplicate_targets
712- if dedupe :
713- avoid .update ((self .query .dupe_avoidance .get (id (opts ), lhs_col ),
714- ()))
715- dupe_set .add ((opts , lhs_col ))
716675 int_opts = int_model ._meta
717676 alias = self .query .join (
718677 (alias , int_opts .db_table , lhs_col , int_opts .pk .column ),
719- exclusions = used , promote = True , reuse = used
678+ promote = True ,
720679 )
721680 alias_chain .append (alias )
722- for dupe_opts , dupe_col in dupe_set :
723- self .query .update_dupe_avoidance (dupe_opts , dupe_col , alias )
724- dedupe = f .column in opts .duplicate_targets
725- if dupe_set or dedupe :
726- avoid .update (self .query .dupe_avoidance .get ((id (opts ), f .column ), ()))
727- if dedupe :
728- dupe_set .add ((opts , f .column ))
729681 alias = self .query .join (
730682 (alias , table , f .rel .get_related_field ().column , f .column ),
731- exclusions = used .union (avoid ),
732683 promote = True
733684 )
734- used .add (alias )
735685 columns , aliases = self .get_default_columns (start_alias = alias ,
736686 opts = model ._meta , as_pairs = True , local_only = True )
737687 self .query .related_select_cols .extend (
@@ -743,7 +693,7 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
743693 new_nullable = True
744694
745695 self .fill_related_selections (model ._meta , table , cur_depth + 1 ,
746- used , next , restricted , new_nullable )
696+ next , restricted , new_nullable )
747697
748698 def deferred_to_columns (self ):
749699 """
0 commit comments