@@ -420,6 +420,14 @@ func (qs *queryState) handleValuePostings(ctx context.Context, args funcArgs) er
420420 outputs := make ([]* pb.Result , numGo )
421421 listType := schema .State ().IsList (q .Attr )
422422
423+ // These are certain special cases where we can get away with reading only the latest value
424+ // Lang doesn't work because we would be storing various different languages at various
425+ // time. So when we go to read the latest value, we might get a different language.
426+ // Similarly with DoCount and ExpandAll and Facets. List types are also not supported
427+ // because list is stored by time, and we combine all the list items at various timestamps.
428+ hasLang := schema .State ().HasLang (q .Attr )
429+ getMultiplePosting := q .DoCount || q .ExpandAll || listType || hasLang || q .FacetParam != nil
430+
423431 calculate := func (start , end int ) error {
424432 x .AssertTrue (start % width == 0 )
425433 out := & pb.Result {}
@@ -434,49 +442,75 @@ func (qs *queryState) handleValuePostings(ctx context.Context, args funcArgs) er
434442 key := x .DataKey (q .Attr , q .UidList .Uids [i ])
435443
436444 // Get or create the posting list for an entity, attribute combination.
437- pl , err := qs .cache .Get (key )
438- if err != nil {
439- return err
440- }
441445
442- // If count is being requested, there is no need to populate value and facets matrix.
443- if q .DoCount {
444- count , err := countForValuePostings (args , pl , facetsTree , listType )
445- if err != nil && err != posting .ErrNoValue {
446+ var vals []types.Val
447+ fcs := & pb.FacetsList {FacetsList : make ([]* pb.Facets , 0 )} // TODO Figure out how it is stored
448+
449+ if ! getMultiplePosting {
450+ pl , err := qs .cache .GetSinglePosting (key )
451+ if err != nil {
452+ return err
453+ }
454+ if pl == nil || len (pl .Postings ) == 0 {
455+ out .UidMatrix = append (out .UidMatrix , & pb.List {})
456+ out .FacetMatrix = append (out .FacetMatrix , & pb.FacetsList {})
457+ out .ValueMatrix = append (out .ValueMatrix ,
458+ & pb.ValueList {Values : []* pb.TaskValue {}})
459+ continue
460+ }
461+ vals = make ([]types.Val , len (pl .Postings ))
462+ for i , p := range pl .Postings {
463+ vals [i ] = types.Val {
464+ Tid : types .TypeID (p .ValType ),
465+ Value : p .Value ,
466+ }
467+ }
468+ } else {
469+ pl , err := qs .cache .Get (key )
470+ if err != nil {
446471 return err
447472 }
448- out .Counts = append (out .Counts , uint32 (count ))
449- // Add an empty UID list to make later processing consistent.
450- out .UidMatrix = append (out .UidMatrix , & pb.List {})
451- continue
452- }
453473
454- vals , fcs , err := retrieveValuesAndFacets (args , pl , facetsTree , listType )
455- switch {
456- case err == posting .ErrNoValue || (err == nil && len (vals ) == 0 ):
457- // This branch is taken when the value does not exist in the pl or
458- // the number of values retrieved is zero (there could still be facets).
459- // We add empty lists to the UidMatrix, FaceMatrix, ValueMatrix and
460- // LangMatrix so that all these data structure have predictable layouts.
461- out .UidMatrix = append (out .UidMatrix , & pb.List {})
462- out .FacetMatrix = append (out .FacetMatrix , & pb.FacetsList {})
463- out .ValueMatrix = append (out .ValueMatrix ,
464- & pb.ValueList {Values : []* pb.TaskValue {}})
465- if q .ExpandAll {
466- // To keep the cardinality same as that of ValueMatrix.
467- out .LangMatrix = append (out .LangMatrix , & pb.LangList {})
474+ // If count is being requested, there is no need to populate value and facets matrix.
475+ if q .DoCount {
476+ count , err := countForValuePostings (args , pl , facetsTree , listType )
477+ if err != nil && err != posting .ErrNoValue {
478+ return err
479+ }
480+ out .Counts = append (out .Counts , uint32 (count ))
481+ // Add an empty UID list to make later processing consistent.
482+ out .UidMatrix = append (out .UidMatrix , & pb.List {})
483+ continue
468484 }
469- continue
470- case err != nil :
471- return err
472- }
473485
474- if q .ExpandAll {
475- langTags , err := pl .GetLangTags (args .q .ReadTs )
476- if err != nil {
486+ vals , fcs , err = retrieveValuesAndFacets (args , pl , facetsTree , listType )
487+
488+ switch {
489+ case err == posting .ErrNoValue || (err == nil && len (vals ) == 0 ):
490+ // This branch is taken when the value does not exist in the pl or
491+ // the number of values retrieved is zero (there could still be facets).
492+ // We add empty lists to the UidMatrix, FaceMatrix, ValueMatrix and
493+ // LangMatrix so that all these data structure have predictable layouts.
494+ out .UidMatrix = append (out .UidMatrix , & pb.List {})
495+ out .FacetMatrix = append (out .FacetMatrix , & pb.FacetsList {})
496+ out .ValueMatrix = append (out .ValueMatrix ,
497+ & pb.ValueList {Values : []* pb.TaskValue {}})
498+ if q .ExpandAll {
499+ // To keep the cardinality same as that of ValueMatrix.
500+ out .LangMatrix = append (out .LangMatrix , & pb.LangList {})
501+ }
502+ continue
503+ case err != nil :
477504 return err
478505 }
479- out .LangMatrix = append (out .LangMatrix , & pb.LangList {Lang : langTags })
506+
507+ if q .ExpandAll {
508+ langTags , err := pl .GetLangTags (args .q .ReadTs )
509+ if err != nil {
510+ return err
511+ }
512+ out .LangMatrix = append (out .LangMatrix , & pb.LangList {Lang : langTags })
513+ }
480514 }
481515
482516 uidList := new (pb.List )
0 commit comments