code: func (c *shellQueryClient) Range(ctx context.Context, ops []*queryObj, fields []string, limit int) ([]map[string]dosa.FieldValue, error) {
  	// look up the entity in the registry
  	re, _ := c.registrar.Find(&dosa.Entity{})
  
  	// build range operator with expressions and limit number
  	r, err := buildRangeOp(ops, limit)
  	if err != nil {
  		return nil, err
  	}
  
  	// now convert the client range columns to server side column conditions structure
  	columnConditions, err := dosa.ConvertConditions(r.Conditions(), re.Table())
  	if err != nil {
  		return nil, err
  	}
  
  	// convert the field names to column names
  	columns, err := re.ColumnNames(fields)
  	if err != nil {
  		return nil, err
  	}
  
  	// call the server side method
  	values, _, err := c.connector.Range(ctx, re.EntityInfo(), columnConditions, columns, "", r.LimitRows())
  	if err != nil {
  		return nil, err
  	}
  
  	return convertColToField(values, re.Table().ColToField), err
  }
docs: // Range uses the connector to fetch rows for a given range