Merge pull request #288 from travisturner/upgrade-min-max

upgrade decimal min/max with scale
This commit is contained in:
Travis Turner 2020-04-15 08:08:00 -05:00 committed by GitHub
commit 37f05fc3ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 2 deletions

View file

@ -2967,6 +2967,16 @@ func (e *executor) executeSet(ctx context.Context, index string, c *pql.Call, op
if !ok {
return false, fmt.Errorf("Set() row argument '%v' required", rowLabel)
}
// Before we scale a decimal to an integer, we need to make sure the decimal
// is between min/max for the field. If it's not, converting to an integer
// can result in an overflow.
if dec, ok := v.(pql.Decimal); ok && f.Options().Type == FieldTypeDecimal {
if dec.LessThan(f.Options().Min) || dec.GreaterThan(f.Options().Max) {
return false, ErrDecimalOutOfRange
}
}
// Read row value.
rowVal, err := getScaledInt(f, v)
if err != nil {

View file

@ -5251,6 +5251,23 @@ func TestExecutor_Execute_MinMaxCountEqual(t *testing.T) {
}
}
})
t.Run("MinMaxRangeError", func(t *testing.T) {
// Min
pql := `Set(4, dec=-92233720368547758.08)`
if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err == nil {
t.Fatalf("expected error but got: nil")
} else if errors.Cause(err) != pilosa.ErrDecimalOutOfRange {
t.Fatalf("expected error: %s, but got: %s", pilosa.ErrDecimalOutOfRange, err)
}
// Max
pql = `Set(4, dec=92233720368547758.07)`
if _, err := c[0].API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: pql}); err == nil {
t.Fatalf("expected error but got: nil")
} else if errors.Cause(err) != pilosa.ErrDecimalOutOfRange {
t.Fatalf("expected error: %s, but got: %s", pilosa.ErrDecimalOutOfRange, err)
}
})
}
func TestExecutor_Execute_NoIndex(t *testing.T) {

View file

@ -800,13 +800,13 @@ func (f *Field) loadMeta() error {
if pb.Min != nil {
min = pql.NewDecimal(pb.Min.Value, pb.Min.Scale)
} else {
min = pql.NewDecimal(pb.OldMin, 0)
min = pql.NewDecimal(pb.OldMin, pb.Scale)
}
var max pql.Decimal
if pb.Max != nil {
max = pql.NewDecimal(pb.Max.Value, pb.Max.Scale)
} else {
max = pql.NewDecimal(pb.OldMax, 0)
max = pql.NewDecimal(pb.OldMax, pb.Scale)
}
// Initialize "base" to "min" when upgrading from v1 BSI format.

View file

@ -46,6 +46,7 @@ var (
ErrBSIGroupValueTooHigh = errors.New("bsigroup value too high")
ErrInvalidRangeOperation = errors.New("invalid range operation")
ErrInvalidBetweenValue = errors.New("invalid value for between operation")
ErrDecimalOutOfRange = errors.New("decimal value out of range")
ErrInvalidView = errors.New("invalid view")
ErrInvalidCacheType = errors.New("invalid cache type")

View file

@ -425,6 +425,8 @@ func quotient(d Decimal) int64 {
return d.Value
} else if d.Scale > 0 && d.Scale < 19 {
return d.Value / pow10[d.Scale]
} else if d.Scale < 0 && d.Scale > -19 {
return d.Value * pow10[-1*d.Scale]
}
return 0
}