8
8
9
9
from __future__ import annotations
10
10
11
+ import collections
11
12
import itertools
12
13
from typing import Any
13
14
from typing import cast
@@ -2494,31 +2495,83 @@ def _adjust_for_extra_criteria(self):
2494
2495
ext_info ._adapter if ext_info .is_aliased_class else None ,
2495
2496
)
2496
2497
2497
- search = set ( self . extra_criteria_entities . values () )
2498
+ _where_criteria_to_add = ( )
2498
2499
2499
- for ext_info , adapter in search :
2500
+ merged_single_crit = collections .defaultdict (
2501
+ lambda : (util .OrderedSet (), set ())
2502
+ )
2503
+
2504
+ for ext_info , adapter in util .OrderedSet (
2505
+ self .extra_criteria_entities .values ()
2506
+ ):
2500
2507
if ext_info in self ._join_entities :
2501
2508
continue
2502
2509
2503
- single_crit = ext_info .mapper ._single_table_criterion
2504
-
2505
- if self .compile_options ._for_refresh_state :
2506
- additional_entity_criteria = []
2510
+ # assemble single table inheritance criteria.
2511
+ if (
2512
+ ext_info .is_aliased_class
2513
+ and ext_info ._base_alias ()._is_with_polymorphic
2514
+ ):
2515
+ # for a with_polymorphic(), we always include the full
2516
+ # hierarchy from what's given as the base class for the wpoly.
2517
+ # this is new in 2.1 for #12395 so that it matches the behavior
2518
+ # of joined inheritance.
2519
+ hierarchy_root = ext_info ._base_alias ()
2507
2520
else :
2508
- additional_entity_criteria = self . _get_extra_criteria ( ext_info )
2521
+ hierarchy_root = ext_info
2509
2522
2510
- if single_crit is not None :
2511
- additional_entity_criteria += (single_crit ,)
2523
+ single_crit_component = (
2524
+ hierarchy_root .mapper ._single_table_criteria_component
2525
+ )
2512
2526
2513
- current_adapter = self ._get_current_adapter ()
2514
- for crit in additional_entity_criteria :
2527
+ if single_crit_component is not None :
2528
+ polymorphic_on , criteria = single_crit_component
2529
+
2530
+ polymorphic_on = polymorphic_on ._annotate (
2531
+ {
2532
+ "parententity" : hierarchy_root ,
2533
+ "parentmapper" : hierarchy_root .mapper ,
2534
+ }
2535
+ )
2536
+
2537
+ list_of_single_crits , adapters = merged_single_crit [
2538
+ (hierarchy_root , polymorphic_on )
2539
+ ]
2540
+ list_of_single_crits .update (criteria )
2515
2541
if adapter :
2516
- crit = adapter . traverse ( crit )
2542
+ adapters . add ( adapter )
2517
2543
2518
- if current_adapter :
2519
- crit = sql_util ._deep_annotate (crit , {"_orm_adapt" : True })
2520
- crit = current_adapter (crit , False )
2544
+ # assemble "additional entity criteria", which come from
2545
+ # with_loader_criteria() options
2546
+ if not self .compile_options ._for_refresh_state :
2547
+ additional_entity_criteria = self ._get_extra_criteria (ext_info )
2548
+ _where_criteria_to_add += tuple (
2549
+ adapter .traverse (crit ) if adapter else crit
2550
+ for crit in additional_entity_criteria
2551
+ )
2552
+
2553
+ # merge together single table inheritance criteria keyed to
2554
+ # top-level mapper / aliasedinsp (which may be a with_polymorphic())
2555
+ for (ext_info , polymorphic_on ), (
2556
+ merged_crit ,
2557
+ adapters ,
2558
+ ) in merged_single_crit .items ():
2559
+ new_crit = polymorphic_on .in_ (merged_crit )
2560
+ for adapter in adapters :
2561
+ new_crit = adapter .traverse (new_crit )
2562
+ _where_criteria_to_add += (new_crit ,)
2563
+
2564
+ current_adapter = self ._get_current_adapter ()
2565
+ if current_adapter :
2566
+ # finally run all the criteria through the "main" adapter, if we
2567
+ # have one, and concatenate to final WHERE criteria
2568
+ for crit in _where_criteria_to_add :
2569
+ crit = sql_util ._deep_annotate (crit , {"_orm_adapt" : True })
2570
+ crit = current_adapter (crit , False )
2521
2571
self ._where_criteria += (crit ,)
2572
+ else :
2573
+ # else just concatenate our criteria to the final WHERE criteria
2574
+ self ._where_criteria += _where_criteria_to_add
2522
2575
2523
2576
2524
2577
def _column_descriptions (
@@ -2552,7 +2605,7 @@ def _column_descriptions(
2552
2605
2553
2606
2554
2607
def _legacy_filter_by_entity_zero (
2555
- query_or_augmented_select : Union [Query [Any ], Select [Unpack [TupleAny ]]]
2608
+ query_or_augmented_select : Union [Query [Any ], Select [Unpack [TupleAny ]]],
2556
2609
) -> Optional [_InternalEntityType [Any ]]:
2557
2610
self = query_or_augmented_select
2558
2611
if self ._setup_joins :
@@ -2567,7 +2620,7 @@ def _legacy_filter_by_entity_zero(
2567
2620
2568
2621
2569
2622
def _entity_from_pre_ent_zero (
2570
- query_or_augmented_select : Union [Query [Any ], Select [Unpack [TupleAny ]]]
2623
+ query_or_augmented_select : Union [Query [Any ], Select [Unpack [TupleAny ]]],
2571
2624
) -> Optional [_InternalEntityType [Any ]]:
2572
2625
self = query_or_augmented_select
2573
2626
if not self ._raw_columns :
0 commit comments