code: func ScanIndexData(sc *stmtctx.StatementContext, txn kv.Transaction, kvIndex table.Index, startVals []types.Datum, limit int64) (
  	[]*RecordData, []types.Datum, error) {
  	it, _, err := kvIndex.Seek(sc, txn, startVals)
  	if err != nil {
  		return nil, nil, errors.Trace(err)
  	}
  	defer it.Close()
  
  	var idxRows []*RecordData
  	var curVals []types.Datum
  	for limit != 0 {
  		val, h, err1 := it.Next()
  		if terror.ErrorEqual(err1, io.EOF) {
  			return idxRows, nextIndexVals(curVals), nil
  		} else if err1 != nil {
  			return nil, nil, errors.Trace(err1)
  		}
  		idxRows = append(idxRows, &RecordData{Handle: h, Values: val})
  		limit--
  		curVals = val
  	}
  
  	nextVals, _, err := it.Next()
  	if terror.ErrorEqual(err, io.EOF) {
  		return idxRows, nextIndexVals(curVals), nil
  	} else if err != nil {
  		return nil, nil, errors.Trace(err)
  	}
  
  	return idxRows, nextVals, nil
  }
docs: // ScanIndexData scans the index handles and values in a limited number, according to the index information.
  // It returns data and the next startVals until it doesn't have data, then returns data is nil and
  // the next startVals is the values which can't get data. If startVals = nil and limit = -1,
  // it returns the index data of the whole.