diff --git a/pkg/settings/enum.go b/pkg/settings/enum.go index 013d3a4059c8..becebdeac9bb 100644 --- a/pkg/settings/enum.go +++ b/pkg/settings/enum.go @@ -59,6 +59,24 @@ func (e *EnumSetting) ParseEnum(raw string) (int64, bool) { return v, ok } +// GetAvailableValuesAsHint returns the possible enum settings as a string that +// can be provided as an error hint to a user. +func (e *EnumSetting) GetAvailableValuesAsHint() string { + // First stabilize output by sorting by key. + valIdxs := make([]int, 0, len(e.enumValues)) + for i := range e.enumValues { + valIdxs = append(valIdxs, int(i)) + } + sort.Ints(valIdxs) + + // Now use those indices + vals := make([]string, 0, len(e.enumValues)) + for _, enumIdx := range valIdxs { + vals = append(vals, fmt.Sprintf("%d: %s", enumIdx, e.enumValues[int64(enumIdx)])) + } + return "Available values: " + strings.Join(vals, ", ") +} + func (e *EnumSetting) set(sv *Values, k int64) error { if _, ok := e.enumValues[k]; !ok { return errors.Errorf("unrecognized value %d", k) diff --git a/pkg/sql/set_cluster_setting.go b/pkg/sql/set_cluster_setting.go index 8bea2b2f9314..02983a68f6fe 100644 --- a/pkg/sql/set_cluster_setting.go +++ b/pkg/sql/set_cluster_setting.go @@ -290,14 +290,14 @@ func toSettingString( if ok { return settings.EncodeInt(v), nil } - return "", errors.Errorf("invalid integer value '%d' for enum setting", *i) + return "", errors.WithHintf(errors.Errorf("invalid integer value '%d' for enum setting", *i), setting.GetAvailableValuesAsHint()) } else if s, ok := d.(*tree.DString); ok { str := string(*s) v, ok := setting.ParseEnum(str) if ok { return settings.EncodeInt(v), nil } - return "", errors.Errorf("invalid string value '%s' for enum setting", str) + return "", errors.WithHintf(errors.Errorf("invalid string value '%s' for enum setting", str), setting.GetAvailableValuesAsHint()) } return "", errors.Errorf("cannot use %s %T value for enum setting, must be int or string", d.ResolvedType(), d) case *settings.ByteSizeSetting: