@@ -606,6 +606,76 @@ describe('live repository authorization follows ranked candidates', () => {
606606 )
607607 } )
608608
609+ it ( 'restarts exact ranking at zero and advances past already considered ANN candidates' , async ( ) => {
610+ const probe = Array . from ( { length : 200 } , ( _ , index ) =>
611+ candidate ( `probe-${ index } ` , 'allowed-source' )
612+ )
613+ const approximate = Array . from ( { length : 20 } , ( _ , index ) =>
614+ candidate ( `approximate-${ index } ` , 'allowed-source' )
615+ )
616+ queueTableRows ( schemaMock . embedding , probe )
617+ queueTableRows ( schemaMock . embedding , approximate )
618+ queueTableRows ( schemaMock . embedding , [ ] )
619+ queueTableRows ( schemaMock . embedding , probe )
620+ queueTableRows ( schemaMock . embedding , [ ] )
621+ queueTableRows ( schemaMock . embedding , approximate )
622+ queueTableRows ( schemaMock . embedding , probe )
623+ queueTableRows ( schemaMock . embedding , [ candidate ( 'selected' , 'allowed-source' ) ] )
624+ queueTableRows ( schemaMock . embedding , [
625+ { id : 'selected' , content : 'Reachable after the exact restart' , distance : 0.1 } ,
626+ ] )
627+
628+ const rows = await handleVectorOnlySearch ( { ...params , structuredFilters : undefined } )
629+
630+ expect ( rows . map ( ( row ) => row . id ) ) . toEqual ( [ 'selected' ] )
631+ expect ( dbChainMockFns . offset . mock . calls ) . toEqual ( [ [ 0 ] , [ 20 ] , [ 0 ] , [ 20 ] ] )
632+ expect ( getForConnectors ) . toHaveBeenCalledTimes ( 2 )
633+ expect ( dbChainMockFns . transaction ) . toHaveBeenCalledTimes ( 3 )
634+ } )
635+
636+ it ( 'keeps the nearest exact results when an earlier ANN page hydrated only a farther result' , async ( ) => {
637+ const probe = Array . from ( { length : 200 } , ( _ , index ) =>
638+ candidate ( `probe-${ index } ` , 'allowed-source' )
639+ )
640+ queueTableRows ( schemaMock . embedding , probe )
641+ queueTableRows ( schemaMock . embedding , [
642+ { ...candidate ( 'far' , 'allowed-source' ) , distance : 0.7 } ,
643+ ...Array . from ( { length : 19 } , ( _ , index ) => candidate ( `hidden-${ index } ` , 'allowed-source' ) ) ,
644+ ] )
645+ queueTableRows ( schemaMock . embedding , [ { id : 'far' , content : 'Far result' , distance : 0.7 } ] )
646+ queueTableRows ( schemaMock . embedding , probe )
647+ queueTableRows ( schemaMock . embedding , [ ] )
648+ queueTableRows ( schemaMock . embedding , [
649+ candidate ( 'near' , 'allowed-source' ) ,
650+ candidate ( 'nearer' , 'allowed-source' ) ,
651+ candidate ( 'far' , 'allowed-source' ) ,
652+ ] )
653+ queueTableRows ( schemaMock . embedding , [
654+ { id : 'near' , content : 'Near result' , distance : 0.2 } ,
655+ { id : 'nearer' , content : 'Nearest result' , distance : 0.1 } ,
656+ ] )
657+
658+ const rows = await handleVectorOnlySearch ( {
659+ ...params ,
660+ topK : 2 ,
661+ structuredFilters : undefined ,
662+ } )
663+
664+ expect ( rows . map ( ( row ) => row . id ) ) . toEqual ( [ 'nearer' , 'near' ] )
665+ expect ( dbChainMockFns . offset . mock . calls ) . toEqual ( [ [ 0 ] , [ 20 ] , [ 0 ] ] )
666+ expect (
667+ hasMockCondition (
668+ dbChainMockFns . where . mock . calls . at ( - 1 ) ! [ 0 ] ,
669+ ( node ) =>
670+ node . type === 'inArray' &&
671+ node . column === schemaMock . embedding . id &&
672+ Array . isArray ( node . values ) &&
673+ node . values . length === 2 &&
674+ ! node . values . includes ( 'far' )
675+ )
676+ ) . toBe ( true )
677+ } )
678+
609679 it . each ( [ 'vector' , 'tag-vector' , 'tags' , 'keyword' ] as const ) (
610680 '%s ranks identifiers before verification and loads content under the full predicate' ,
611681 async ( mode ) => {
0 commit comments