@@ -1738,3 +1738,83 @@ func TestCrudWithNoMMap(t *testing.T) {
1738
1738
}
1739
1739
}
1740
1740
}
1741
+
1742
+ // TestBug87 reproduces a situation in which a search matches several documents
1743
+ // and we compare the document's stored value for the _id field, with the
1744
+ // document's sort value. The sort value should be the same _id, but
1745
+ // comes from the doc values storage.
1746
+ // In this case, because doc values were loaded from multiple chunks, an
1747
+ // "uncompressed" buffer is reused. Incorrect use of of these doc values
1748
+ // bytes in computed sort values may lead to incorrect sort order and other
1749
+ // undesired behavior.
1750
+ func TestBug87 (t * testing.T ) {
1751
+ tmpIndexPath := createTmpIndexPath (t )
1752
+ defer cleanupTmpIndexPath (t , tmpIndexPath )
1753
+
1754
+ config := DefaultConfig (tmpIndexPath )
1755
+ indexWriter , err := OpenWriter (config )
1756
+ if err != nil {
1757
+ t .Fatal (err )
1758
+ }
1759
+ defer func () {
1760
+ err = indexWriter .Close ()
1761
+ if err != nil {
1762
+ t .Fatal (err )
1763
+ }
1764
+ }()
1765
+
1766
+ // create 1025 documents in a batch
1767
+ // this should require more than one chunk in doc values
1768
+ batch := NewBatch ()
1769
+ for i := 0 ; i < 1025 ; i ++ {
1770
+ doc := NewDocument (fmt .Sprintf ("%d" , i )).
1771
+ AddField (NewTextField ("name" , "marty" ).Sortable ())
1772
+ batch .Update (doc .ID (), doc )
1773
+ }
1774
+
1775
+ err = indexWriter .Batch (batch )
1776
+ if err != nil {
1777
+ t .Error (err )
1778
+ }
1779
+
1780
+ reader , err := indexWriter .Reader ()
1781
+ if err != nil {
1782
+ t .Fatal (err )
1783
+ }
1784
+ defer func () {
1785
+ err = reader .Close ()
1786
+ if err != nil {
1787
+ t .Fatal (err )
1788
+ }
1789
+ }()
1790
+
1791
+ q := NewTermQuery ("marty" ).SetField ("name" )
1792
+ req := NewTopNSearch (2000 , q ).SortBy ([]string {"_id" })
1793
+
1794
+ dmi , err := reader .Search (context .Background (), req )
1795
+ if err != nil {
1796
+ t .Fatal (err )
1797
+ }
1798
+
1799
+ next , err := dmi .Next ()
1800
+ for err == nil && next != nil {
1801
+ var id string
1802
+ err = next .VisitStoredFields (func (field string , value []byte ) bool {
1803
+ if field == "_id" {
1804
+ id = string (value )
1805
+ return false
1806
+ }
1807
+ return true
1808
+ })
1809
+ if err != nil {
1810
+ t .Fatal (err )
1811
+ }
1812
+ if string (next .SortValue [0 ]) != id {
1813
+ t .Fatalf ("expected id '%s' to match sort value '%s'" , id , string (next .SortValue [0 ]))
1814
+ }
1815
+ next , err = dmi .Next ()
1816
+ }
1817
+ if err != nil {
1818
+ t .Fatal (err )
1819
+ }
1820
+ }
0 commit comments