@@ -354,13 +354,14 @@ impl<'a> Join<'a> {
354354 }
355355
356356 /// Perform the join. The child nodes are distributed into the parent nodes
357- /// according to the join condition, and are stored in the `response_key`
358- /// entry in each parent's `children` map.
357+ /// according to the `parent_id` returned by the database in each child as
358+ /// attribute `g$parent_id`, and are stored in the `response_key` entry
359+ /// in each parent's `children` map.
359360 ///
360361 /// The `children` must contain the nodes in the correct order for each
361362 /// parent; we simply pick out matching children for each parent but
362363 /// otherwise maintain the order in `children`
363- fn perform ( & self , parents : & mut Vec < Node > , children : Vec < Node > , response_key : & str ) {
364+ fn perform ( parents : & mut Vec < Node > , children : Vec < Node > , response_key : & str ) {
364365 let children: Vec < _ > = children. into_iter ( ) . map ( |child| Rc :: new ( child) ) . collect ( ) ;
365366
366367 if parents. len ( ) == 1 {
@@ -369,92 +370,43 @@ impl<'a> Join<'a> {
369370 return ;
370371 }
371372
372- // Organize the join conditions by child type. We do not precompute that
373- // in `new`, because `perform` is only called once for each instance
374- // of a `Join`. For each child type, there might be multiple parent
375- // types that require different ways of joining to them
376- let conds_by_child: HashMap < _ , Vec < _ > > =
377- self . conds . iter ( ) . fold ( HashMap :: default ( ) , |mut map, cond| {
378- map. entry ( cond. child_type ) . or_default ( ) . push ( cond) ;
379- map
380- } ) ;
381-
382- // Build a map (parent_type, child_key) -> Vec<child> for joining by grouping
383- // children by their child_field
384- let mut grouped: BTreeMap < ( & str , & str ) , Vec < Rc < Node > > > = BTreeMap :: default ( ) ;
373+ // Build a map parent_id -> Vec<child> that we will use to add
374+ // children to their parent. This relies on the fact that interfaces
375+ // make sure that id's are distinct across all implementations of the
376+ // interface.
377+ let mut grouped: BTreeMap < & str , Vec < Rc < Node > > > = BTreeMap :: default ( ) ;
385378 for child in children. iter ( ) {
386- for cond in conds_by_child. get ( child. typename ( ) ) . expect ( & format ! (
387- "query results only contain known types: {}" ,
388- child. typename( )
389- ) ) {
390- match child
391- . get ( "g$parent_id" )
392- . expect ( "the query that produces 'child' ensures there is always a g$parent_id" )
393- {
394- StoreValue :: String ( key) => grouped
395- . entry ( ( cond. parent_type , key) )
396- . or_default ( )
397- . push ( child. clone ( ) ) ,
398- StoreValue :: List ( list) => {
399- for key in list {
400- match key {
401- StoreValue :: String ( key) => grouped
402- . entry ( ( cond. parent_type , key) )
403- . or_default ( )
404- . push ( child. clone ( ) ) ,
405- _ => unreachable ! ( "a list of join keys contains only strings" ) ,
406- }
407- }
408- }
409- _ => unreachable ! ( "join fields are strings or lists" ) ,
410- }
379+ match child
380+ . get ( "g$parent_id" )
381+ . expect ( "the query that produces 'child' ensures there is always a g$parent_id" )
382+ {
383+ StoreValue :: String ( key) => grouped. entry ( key) . or_default ( ) . push ( child. clone ( ) ) ,
384+ _ => unreachable ! ( "the parent_id returned by the query is always a string" ) ,
411385 }
412386 }
413387
414- // Organize the join conditions by parent type.
415- let conds_by_parent: HashMap < _ , Vec < _ > > =
416- self . conds . iter ( ) . fold ( HashMap :: default ( ) , |mut map, cond| {
417- map. entry ( cond. parent_type ) . or_default ( ) . push ( cond) ;
418- map
419- } ) ;
420-
421388 // Add appropriate children using grouped map
422389 for parent in parents. iter_mut ( ) {
423- // It is possible that we do not have a join condition for some
424- // parent types. That can happen, for example, if the parents
425- // were the result of querying for an interface type, and we
426- // have to get children for some of the parents, but not others.
427- // If a parent type is not mentioned in any join conditions,
428- // we skip it by looping over an empty vector.
429- //
430- // See the test interface_inline_fragment_with_subquery in
431- // core/tests/interfaces.rs for an example.
432- for cond in conds_by_parent. get ( parent. typename ( ) ) . unwrap_or ( & vec ! [ ] ) {
433- // Set the `response_key` field in `parent`. Make sure that even
434- // if `parent` has no matching `children`, the field gets set (to
435- // an empty `Vec`)
436- // This is complicated by the fact that, if there was a type
437- // condition, we should only change parents that meet the type
438- // condition; we set it for all parents regardless, as that does
439- // not cause problems in later processing, but make sure that we
440- // do not clobber an entry under this `response_key` that might
441- // have been set by a previous join by appending values rather
442- // than using straight insert into the parent
443- let mut values = parent
444- . id ( )
445- . ok ( )
446- . and_then ( |id| {
447- grouped
448- . get ( & ( cond. parent_type , & id) )
449- . map ( |values| values. clone ( ) )
450- } )
451- . unwrap_or ( vec ! [ ] ) ;
452- parent
453- . children
454- . entry ( response_key. to_owned ( ) )
455- . or_default ( )
456- . append ( & mut values) ;
457- }
390+ // Set the `response_key` field in `parent`. Make sure that even
391+ // if `parent` has no matching `children`, the field gets set (to
392+ // an empty `Vec`)
393+ // This is complicated by the fact that, if there was a type
394+ // condition, we should only change parents that meet the type
395+ // condition; we set it for all parents regardless, as that does
396+ // not cause problems in later processing, but make sure that we
397+ // do not clobber an entry under this `response_key` that might
398+ // have been set by a previous join by appending values rather
399+ // than using straight insert into the parent
400+ let mut values = parent
401+ . id ( )
402+ . ok ( )
403+ . and_then ( |id| grouped. get ( & * id) . map ( |values| values. clone ( ) ) )
404+ . unwrap_or ( vec ! [ ] ) ;
405+ parent
406+ . children
407+ . entry ( response_key. to_owned ( ) )
408+ . or_default ( )
409+ . append ( & mut values) ;
458410 }
459411 }
460412
@@ -668,7 +620,7 @@ where
668620 & child_object_type,
669621 ) {
670622 Ok ( children) => {
671- join . perform ( & mut parents, children, response_key)
623+ Join :: perform ( & mut parents, children, response_key)
672624 }
673625 Err ( mut e) => errors. append ( & mut e) ,
674626 }
0 commit comments