Skip to content

Commit

Permalink
geo,sql: add some missing pg error codes
Browse files Browse the repository at this point in the history
This commit adds a bunch of missing pg error codes to builtins. It also
adds missing codes for when the optimizer fails to satisfy an index
hint.

Release note (sql change): several error cases in geospatial and other
builtins returned "internal error" pg error codes. They now return more
appropriate error codes. This is a minor change and clients should not
notice.
  • Loading branch information
jordanlewis committed Feb 12, 2022
1 parent 1fa3617 commit 547d476
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pkg/geo/parse.go
Expand Up @@ -247,7 +247,7 @@ func parseGeoHash(g string, precision int) (geohash.Box, error) {
}
box, err := geohash.Decode(g[:precision])
if err != nil {
return geohash.Box{}, err
return geohash.Box{}, pgerror.Wrap(err, pgcode.InvalidParameterValue, "invalid GeoHash")
}
return box, nil
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/sql/opt/exec/execbuilder/relational.go
Expand Up @@ -535,22 +535,23 @@ func (b *Builder) scanParams(
var err error
switch {
case isInverted && isPartial:
err = fmt.Errorf(
err = pgerror.Newf(pgcode.WrongObjectType,
"index \"%s\" is a partial inverted index and cannot be used for this query",
idx.Name(),
)
case isInverted:
err = fmt.Errorf(
err = pgerror.Newf(pgcode.WrongObjectType,
"index \"%s\" is inverted and cannot be used for this query",
idx.Name(),
)
case isPartial:
err = fmt.Errorf(
err = pgerror.Newf(pgcode.WrongObjectType,
"index \"%s\" is a partial index that does not contain all the rows needed to execute this query",
idx.Name(),
)
default:
err = fmt.Errorf("index \"%s\" cannot be used for this query", idx.Name())
err = pgerror.Newf(pgcode.WrongObjectType,
"index \"%s\" cannot be used for this query", idx.Name())
if b.evalCtx.SessionData().DisallowFullTableScans &&
(b.ContainsLargeFullTableScan || b.ContainsLargeFullIndexScan) {
err = errors.WithHint(err,
Expand Down
10 changes: 5 additions & 5 deletions pkg/sql/sem/builtins/builtins.go
Expand Up @@ -688,7 +688,7 @@ var builtins = map[string]builtinDefinition{
s := string(tree.MustBeDString(args[0]))
uv, err := uuid.FromString(s)
if err != nil {
return nil, err
return nil, pgerror.Wrap(err, pgcode.InvalidParameterValue, "invalid UUID")
}
return tree.NewDBytes(tree.DBytes(uv.GetBytes())), nil
},
Expand Down Expand Up @@ -758,7 +758,7 @@ var builtins = map[string]builtinDefinition{
s := tree.MustBeDString(args[0])
u, err := ulid.Parse(string(s))
if err != nil {
return nil, err
return nil, pgerror.Wrap(err, pgcode.InvalidParameterValue, "invalid ULID")
}
b, err := u.MarshalBinary()
if err != nil {
Expand Down Expand Up @@ -3917,7 +3917,7 @@ value if you rely on the HLC for accuracy.`,
pbToJSON := func(typ string, data []byte, flags protoreflect.FmtFlags) (tree.Datum, error) {
msg, err := protoreflect.DecodeMessage(typ, data)
if err != nil {
return nil, err
return nil, pgerror.Wrap(err, pgcode.InvalidParameterValue, "invalid protocol message")
}
j, err := protoreflect.MessageToJSON(msg, flags)
if err != nil {
Expand Down Expand Up @@ -3998,11 +3998,11 @@ value if you rely on the HLC for accuracy.`,
Fn: func(evalCtx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
msg, err := protoreflect.NewMessage(string(tree.MustBeDString(args[0])))
if err != nil {
return nil, err
return nil, pgerror.Wrap(err, pgcode.InvalidParameterValue, "invalid proto name")
}
data, err := protoreflect.JSONBMarshalToMessage(tree.MustBeDJSON(args[1]).JSON, msg)
if err != nil {
return nil, err
return nil, pgerror.Wrap(err, pgcode.InvalidParameterValue, "invalid proto JSON")
}
return tree.NewDBytes(tree.DBytes(data)), nil
},
Expand Down
6 changes: 3 additions & 3 deletions pkg/sql/sem/builtins/geo_builtins.go
Expand Up @@ -5861,15 +5861,15 @@ See http://developers.google.com/maps/documentation/utilities/polylinealgorithm`
switch bGeomT := bGeomT.(type) {
case *geom.Point:
if aGeomT.Empty() || bGeomT.Empty() {
return nil, errors.Newf("cannot use POINT EMPTY")
return nil, pgerror.Newf(pgcode.InvalidParameterValue, "cannot use POINT EMPTY")
}
bbox := a.CartesianBoundingBox().Combine(b.CartesianBoundingBox())
return tree.NewDBox2D(*bbox), nil
default:
return nil, errors.Newf("second argument is not a POINT")
return nil, pgerror.Newf(pgcode.InvalidParameterValue, "second argument is not a POINT")
}
default:
return nil, errors.Newf("first argument is not a POINT")
return nil, pgerror.Newf(pgcode.InvalidParameterValue, "first argument is not a POINT")
}
},
types.Box2D,
Expand Down
8 changes: 6 additions & 2 deletions pkg/sql/sem/tree/datum.go
Expand Up @@ -2417,7 +2417,9 @@ type DTimestamp struct {
func MakeDTimestamp(t time.Time, precision time.Duration) (*DTimestamp, error) {
ret := t.Round(precision)
if ret.After(MaxSupportedTime) || ret.Before(MinSupportedTime) {
return nil, errors.Newf("timestamp %q exceeds supported timestamp bounds", ret.Format(time.RFC3339))
return nil, pgerror.Newf(
pgcode.InvalidTimeZoneDisplacementValue,
"timestamp %q exceeds supported timestamp bounds", ret.Format(time.RFC3339))
}
return &DTimestamp{Time: ret}, nil
}
Expand Down Expand Up @@ -2699,7 +2701,9 @@ type DTimestampTZ struct {
func MakeDTimestampTZ(t time.Time, precision time.Duration) (*DTimestampTZ, error) {
ret := t.Round(precision)
if ret.After(MaxSupportedTime) || ret.Before(MinSupportedTime) {
return nil, errors.Newf("timestamp %q exceeds supported timestamp bounds", ret.Format(time.RFC3339))
return nil, pgerror.Newf(
pgcode.InvalidTimeZoneDisplacementValue,
"timestamp %q exceeds supported timestamp bounds", ret.Format(time.RFC3339))
}
return &DTimestampTZ{Time: ret}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/sem/tree/eval.go
Expand Up @@ -3063,7 +3063,7 @@ func matchLike(ctx *EvalContext, left, right Datum, caseInsensitive bool) (Datum
func matchRegexpWithKey(ctx *EvalContext, str Datum, key RegexpCacheKey) (Datum, error) {
re, err := ctx.ReCache.GetRegexp(key)
if err != nil {
return DBoolFalse, err
return DBoolFalse, pgerror.Wrap(err, pgcode.InvalidRegularExpression, "invalid regular expression")
}
return MakeDBool(DBool(re.MatchString(string(MustBeDString(str))))), nil
}
Expand Down

0 comments on commit 547d476

Please sign in to comment.