code: func getFields(s interface{}) (ret []reflect.StructField) {
  	val := reflect.Indirect(reflect.ValueOf(s))
  	// addIf adds filedType to ret if is not marked as `sql:"-"`
  	addIf := func(fieldType reflect.StructField) {
  		tag := strings.ToLower(fieldType.Tag.Get("sql"))
  		tagValue := strings.Split(tag, ",")
  		sort.Strings(tagValue)
  		idx := sort.SearchStrings(tagValue, "-")
  		if idx == len(tagValue) || tagValue[idx] != "-" {
  			ret = append(ret, fieldType)
  		}
  	}
  	for i := 0; i < val.NumField(); i++ {
  		fieldValue := val.Field(i)
  		fieldType := val.Type().Field(i)
  		// if it's exported
  		if fieldType.PkgPath == "" {
  			// Handle embedded anoymous struct
  			switch fieldValue.Kind() {
  			case reflect.Struct:
  				// if it's anonymous, embed its fields in the query
  				if fieldType.Anonymous {
  					ret = append(ret, getFields(fieldValue.Interface())...)
  				} else { // use its name only (to work with structs like time.Time)
  					addIf(fieldType)
  				}
  			default:
  				addIf(fieldType)
  			}
  		}
  	}
  
  	return
  }
docs: // getFields returns a slice of reflect.StructField that represents the exported struct Fields in s
  // that are not excluded in sql generation