mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-12 15:51:01 +00:00
make pql.Decimal.Value a private big.Int field
This ensures that we can't overflow when adding `pql.Decimal`s together. The only place we can possibly overflow is when converting pql.Decimal to an Int64, but that is a risk we have to take. Also, the only place we do this is in our ToRowser. We could maybe change that to strings, so the presentation of data doesn't indicate an overflow, but that is a later decision to make. It will also involve fixing the generate-proto-grpc make command, because that's broken rn.
This commit is contained in:
parent
a0c9eec410
commit
eab6174388
21 changed files with 599 additions and 522 deletions
|
|
@ -1210,11 +1210,11 @@ func compareFieldOptions(t *testing.T, opts *FieldOptions, fieldType FieldType,
|
|||
if cacheSize != opts.CacheSize() {
|
||||
t.Fatalf("%d != %d", cacheSize, opts.CacheSize())
|
||||
}
|
||||
if min != opts.Min() {
|
||||
t.Fatalf("%d != %d", min, opts.Min())
|
||||
if !min.EqualTo(opts.Min()) {
|
||||
t.Fatalf("%v != %v", min, opts.Min())
|
||||
}
|
||||
if max != opts.Max() {
|
||||
t.Fatalf("%d != %d", max, opts.Max())
|
||||
if !max.EqualTo(opts.Max()) {
|
||||
t.Fatalf("%v != %v", max, opts.Max())
|
||||
}
|
||||
if foreignIndex != opts.ForeignIndex() {
|
||||
t.Fatalf("%s != %s", foreignIndex, opts.ForeignIndex())
|
||||
|
|
|
|||
|
|
@ -3,15 +3,45 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
pilosa "github.com/molecula/featurebase/v3"
|
||||
"github.com/molecula/featurebase/v3/ctl"
|
||||
"github.com/molecula/featurebase/v3/pql"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var Importer *ctl.ImportCommand
|
||||
|
||||
// DecimalFlagValue is used to set the unexported value field in a decimal. It also
|
||||
// fulfills the flag.Value interface.
|
||||
type DecimalFlagValue struct {
|
||||
dec *pql.Decimal
|
||||
}
|
||||
|
||||
func (dfv *DecimalFlagValue) String() string {
|
||||
return fmt.Sprintf("%v", dfv.dec.Value())
|
||||
}
|
||||
|
||||
func (dfv *DecimalFlagValue) Set(s string) error {
|
||||
i, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dfv.dec == nil {
|
||||
d := pql.NewDecimal(0, 0)
|
||||
dfv.dec = &d
|
||||
}
|
||||
dfv.dec.SetValue(i)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dfv *DecimalFlagValue) Type() string {
|
||||
return fmt.Sprintf("%T", int64(0))
|
||||
}
|
||||
|
||||
// newImportCommand runs the FeatureBase import subcommand for ingesting bulk data.
|
||||
func newImportCommand(stdin io.Reader, stdout, stderr io.Writer) *cobra.Command {
|
||||
Importer = ctl.NewImportCommand(stdin, stdout, stderr)
|
||||
|
|
@ -34,6 +64,8 @@ omitted. If it is present then its format should be YYYY-MM-DDTHH:MM.
|
|||
},
|
||||
}
|
||||
|
||||
fieldMin := DecimalFlagValue{dec: &Importer.FieldOptions.Min}
|
||||
fieldMax := DecimalFlagValue{dec: &Importer.FieldOptions.Max}
|
||||
flags := importCmd.Flags()
|
||||
flags.StringVarP(&Importer.Host, "host", "", "localhost:10101", "host:port of FeatureBase.")
|
||||
flags.StringVarP(&Importer.Index, "index", "i", "", "FeatureBase index to import into.")
|
||||
|
|
@ -41,8 +73,8 @@ omitted. If it is present then its format should be YYYY-MM-DDTHH:MM.
|
|||
flags.BoolVar(&Importer.IndexOptions.Keys, "index-keys", false, "Specify keys=true when creating an index")
|
||||
flags.BoolVar(&Importer.FieldOptions.Keys, "field-keys", false, "Specify keys=true when creating a field")
|
||||
flags.StringVar(&Importer.FieldOptions.Type, "field-type", "", "Specify the field type when creating a field. One of: set, int, decimal, time, bool, mutex")
|
||||
flags.Int64Var(&Importer.FieldOptions.Min.Value, "field-min", 0, "Specify the minimum for an int field on creation") // TODO: noting that decimal field min/max are not supported here.
|
||||
flags.Int64Var(&Importer.FieldOptions.Max.Value, "field-max", 0, "Specify the maximum for an int field on creation")
|
||||
flags.Var(&fieldMin, "field-min", "Specify the minimum for an int field on creation") // TODO: noting that decimal field min/max are not supported here.
|
||||
flags.Var(&fieldMax, "field-max", "Specify the maximum for an int field on creation")
|
||||
flags.StringVar(&Importer.FieldOptions.CacheType, "field-cache-type", pilosa.CacheTypeRanked, "Specify the cache type for a set field on creation. One of: none, lru, ranked")
|
||||
flags.Uint32Var(&Importer.FieldOptions.CacheSize, "field-cache-size", 50000, "Specify the cache size for a set field on creation")
|
||||
flags.Var(&Importer.FieldOptions.TimeQuantum, "field-time-quantum", "Specify the time quantum for a time field on creation. One of: D, DH, H, M, MD, MDH, Y, YM, YMD, YMDH")
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ func (cmd *ImportCommand) Run(ctx context.Context) error {
|
|||
// set the correct type for the field
|
||||
if cmd.FieldOptions.TimeQuantum != "" {
|
||||
cmd.FieldOptions.Type = pilosa.FieldTypeTime
|
||||
} else if cmd.FieldOptions.Min != pql.NewDecimal(0, 0) || cmd.FieldOptions.Max != pql.NewDecimal(0, 0) {
|
||||
} else if !cmd.FieldOptions.Min.EqualTo(pql.NewDecimal(0, 0)) || !cmd.FieldOptions.Max.EqualTo(pql.NewDecimal(0, 0)) {
|
||||
cmd.FieldOptions.Type = pilosa.FieldTypeInt
|
||||
} else {
|
||||
cmd.FieldOptions.Type = pilosa.FieldTypeSet
|
||||
|
|
|
|||
|
|
@ -704,8 +704,8 @@ func (s Serializer) encodeFieldOptions(o *pilosa.FieldOptions) *pb.FieldOptions
|
|||
Type: o.Type,
|
||||
CacheType: o.CacheType,
|
||||
CacheSize: o.CacheSize,
|
||||
Min: &pb.Decimal{Value: o.Min.Value, Scale: o.Min.Scale},
|
||||
Max: &pb.Decimal{Value: o.Max.Value, Scale: o.Max.Scale},
|
||||
Min: s.encodeDecimal(&o.Min),
|
||||
Max: s.encodeDecimal(&o.Max),
|
||||
Base: o.Base,
|
||||
Scale: o.Scale,
|
||||
BitDepth: uint64(o.BitDepth),
|
||||
|
|
@ -1139,8 +1139,11 @@ func (s Serializer) decodeFieldOptions(options *pb.FieldOptions, m *pilosa.Field
|
|||
}
|
||||
|
||||
func (s Serializer) decodeDecimal(d *pb.Decimal, m *pql.Decimal) {
|
||||
m.Value = d.Value
|
||||
m.Scale = d.Scale
|
||||
// err should always be nil, unless there's a problem with the standard library
|
||||
err := m.GobDecode(d.Gob)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s Serializer) decodeNodes(a []*pb.Node, m []*topology.Node) {
|
||||
|
|
@ -1743,10 +1746,9 @@ func (s Serializer) decodeDecimalStruct(pb *pb.Decimal) *pql.Decimal {
|
|||
if pb == nil {
|
||||
return nil
|
||||
}
|
||||
return &pql.Decimal{
|
||||
Value: pb.Value,
|
||||
Scale: pb.Scale,
|
||||
}
|
||||
d := &pql.Decimal{}
|
||||
s.decodeDecimal(pb, d)
|
||||
return d
|
||||
}
|
||||
|
||||
func (s Serializer) encodeSignedRow(r pilosa.SignedRow) *pb.SignedRow {
|
||||
|
|
@ -1962,9 +1964,9 @@ func (s Serializer) encodeDecimal(p *pql.Decimal) *pb.Decimal {
|
|||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
gob, _ := p.GobEncode() // ignore err on purpose
|
||||
return &pb.Decimal{
|
||||
Value: p.Value,
|
||||
Scale: p.Scale,
|
||||
Gob: gob,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
36
executor.go
36
executor.go
|
|
@ -928,9 +928,8 @@ func (e *executor) executeFieldValueCallShard(ctx context.Context, qcx *Qcx, fie
|
|||
if field.Type() == FieldTypeInt {
|
||||
other.Val = value
|
||||
} else if field.Type() == FieldTypeDecimal {
|
||||
other.DecimalVal = &pql.Decimal{
|
||||
Value: value,
|
||||
Scale: field.Options().Scale}
|
||||
dec := pql.NewDecimal(value, field.Options().Scale)
|
||||
other.DecimalVal = &dec
|
||||
other.FloatVal = 0
|
||||
other.Val = 0
|
||||
} else if field.Type() == FieldTypeTimestamp {
|
||||
|
|
@ -1076,9 +1075,8 @@ func (e *executor) executeSum(ctx context.Context, qcx *Qcx, index string, c *pq
|
|||
return ValCount{}, newNotFoundError(ErrFieldNotFound, fieldName)
|
||||
}
|
||||
if field.Type() == FieldTypeDecimal {
|
||||
other.DecimalVal = &pql.Decimal{
|
||||
Value: other.Val,
|
||||
Scale: field.Options().Scale}
|
||||
dec := pql.NewDecimal(other.Val, field.Options().Scale)
|
||||
other.DecimalVal = &dec
|
||||
other.FloatVal = 0
|
||||
other.Val = 0
|
||||
}
|
||||
|
|
@ -1892,7 +1890,8 @@ func (e *executor) executeSumCountShard(ctx context.Context, qcx *Qcx, index str
|
|||
}
|
||||
if field.Type() == FieldTypeDecimal {
|
||||
out.FloatVal = float64(int64(vsum)+(int64(vcount)*bsig.Base)) / math.Pow(10, float64(bsig.Scale))
|
||||
out.DecimalVal = &pql.Decimal{Value: (int64(vsum) + (int64(vcount) * bsig.Base)), Scale: bsig.Scale}
|
||||
dec := pql.NewDecimal((int64(vsum) + (int64(vcount) * bsig.Base)), bsig.Scale)
|
||||
out.DecimalVal = &dec
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
|
@ -3001,11 +3000,7 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c
|
|||
if err := ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
merged, err := mergeGroupCounts(other, findGroupCounts(v), limit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return merged
|
||||
return mergeGroupCounts(other, findGroupCounts(v), limit)
|
||||
}
|
||||
// Get full result set.
|
||||
other, err := e.mapReduce(ctx, index, shards, c, opt, mapFn, reduceFn)
|
||||
|
|
@ -3411,7 +3406,7 @@ func (g *GroupCount) Clone() (r *GroupCount) {
|
|||
// mergeGroupCounts merges two slices of GroupCounts throwing away any that go
|
||||
// beyond the limit. It assume that the two slices are sorted by the row ids in
|
||||
// the fields of the group counts. It may modify its arguments.
|
||||
func mergeGroupCounts(a, b []GroupCount, limit int) ([]GroupCount, error) {
|
||||
func mergeGroupCounts(a, b []GroupCount, limit int) []GroupCount {
|
||||
if limit > len(a)+len(b) {
|
||||
limit = len(a) + len(b)
|
||||
}
|
||||
|
|
@ -3426,10 +3421,7 @@ func mergeGroupCounts(a, b []GroupCount, limit int) ([]GroupCount, error) {
|
|||
a[i].Count += b[j].Count
|
||||
a[i].Agg += b[j].Agg
|
||||
if a[i].DecimalAgg != nil && b[j].DecimalAgg != nil {
|
||||
sum, ok := pql.AddDecimal(*a[i].DecimalAgg, *b[j].DecimalAgg)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot add %s and %s, decimal overflow", a[i].DecimalAgg, b[j].DecimalAgg)
|
||||
}
|
||||
sum := pql.AddDecimal(*a[i].DecimalAgg, *b[j].DecimalAgg)
|
||||
a[i].DecimalAgg = &sum
|
||||
}
|
||||
ret = append(ret, a[i])
|
||||
|
|
@ -3446,7 +3438,7 @@ func mergeGroupCounts(a, b []GroupCount, limit int) ([]GroupCount, error) {
|
|||
for ; j < len(b) && len(ret) < limit; j++ {
|
||||
ret = append(ret, b[j])
|
||||
}
|
||||
return ret, nil
|
||||
return ret
|
||||
}
|
||||
|
||||
// Compare is used in ordering two GroupCount objects.
|
||||
|
|
@ -3981,10 +3973,12 @@ func (t ExtractedTable) ToRows(callback func(*proto.RowResponse) error) error {
|
|||
},
|
||||
}
|
||||
case pql.Decimal:
|
||||
rValue := r.Value()
|
||||
rValuePtr := &rValue
|
||||
col = &proto.ColumnResponse{
|
||||
ColumnVal: &proto.ColumnResponse_DecimalVal{
|
||||
DecimalVal: &proto.Decimal{
|
||||
Value: r.Value,
|
||||
Value: rValuePtr.Int64(),
|
||||
Scale: r.Scale,
|
||||
},
|
||||
},
|
||||
|
|
@ -7670,10 +7664,12 @@ func (v ValCount) ToRows(callback func(*proto.RowResponse) error) error {
|
|||
{Name: "value", Datatype: "decimal"},
|
||||
{Name: "count", Datatype: "int64"},
|
||||
}
|
||||
vValue := v.DecimalVal.Value()
|
||||
vValuePtr := &vValue
|
||||
if err := callback(&proto.RowResponse{
|
||||
Headers: ci,
|
||||
Columns: []*proto.ColumnResponse{
|
||||
{ColumnVal: &proto.ColumnResponse_DecimalVal{DecimalVal: &proto.Decimal{Value: v.DecimalVal.Value, Scale: v.DecimalVal.Scale}}},
|
||||
{ColumnVal: &proto.ColumnResponse_DecimalVal{DecimalVal: &proto.Decimal{Value: vValuePtr.Int64(), Scale: v.DecimalVal.Scale}}},
|
||||
{ColumnVal: &proto.ColumnResponse_Int64Val{Int64Val: v.Count}},
|
||||
}}); err != nil {
|
||||
return errors.Wrap(err, "calling callback")
|
||||
|
|
|
|||
|
|
@ -2269,31 +2269,31 @@ func TestExecutor_Execute_MinMax(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
2,
|
||||
pql.Decimal{Value: 1, Scale: -1},
|
||||
pql.Decimal{Value: 2, Scale: -1},
|
||||
pql.Decimal{Value: 115, Scale: 1},
|
||||
pql.Decimal{Value: 1150, Scale: 2},
|
||||
pql.NewDecimal(1, -1),
|
||||
pql.NewDecimal(2, -1),
|
||||
pql.NewDecimal(115, 1),
|
||||
pql.NewDecimal(1150, 2),
|
||||
},
|
||||
{
|
||||
2,
|
||||
pql.Decimal{Value: -1, Scale: -1},
|
||||
pql.Decimal{Value: 2, Scale: -1},
|
||||
pql.Decimal{Value: 115, Scale: 1},
|
||||
pql.Decimal{Value: 1150, Scale: 2},
|
||||
pql.NewDecimal(-1, -1),
|
||||
pql.NewDecimal(2, -1),
|
||||
pql.NewDecimal(115, 1),
|
||||
pql.NewDecimal(1150, 2),
|
||||
},
|
||||
{
|
||||
2,
|
||||
pql.Decimal{Value: -1, Scale: -1},
|
||||
pql.Decimal{Value: 2, Scale: -1},
|
||||
pql.Decimal{Value: -95, Scale: 1},
|
||||
pql.Decimal{Value: -950, Scale: 2},
|
||||
pql.NewDecimal(-1, -1),
|
||||
pql.NewDecimal(2, -1),
|
||||
pql.NewDecimal(-95, 1),
|
||||
pql.NewDecimal(-950, 2),
|
||||
},
|
||||
{
|
||||
2,
|
||||
pql.Decimal{Value: -2, Scale: -1},
|
||||
pql.Decimal{Value: -1, Scale: -1},
|
||||
pql.Decimal{Value: -115, Scale: 1},
|
||||
pql.Decimal{Value: -1150, Scale: 2},
|
||||
pql.NewDecimal(-2, -1),
|
||||
pql.NewDecimal(-1, -1),
|
||||
pql.NewDecimal(-115, 1),
|
||||
pql.NewDecimal(-1150, 2),
|
||||
},
|
||||
}
|
||||
// This extra field exists to make there be shards which are present,
|
||||
|
|
@ -2849,7 +2849,7 @@ func TestExecutor_Execute_Sum(t *testing.T) {
|
|||
t.Run("NoFilter", func(t *testing.T) {
|
||||
if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(field=dec)`}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &pql.Decimal{Value: 700007, Scale: 3}, Count: 3}) {
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(700007, 3).Clone(), Count: 3}) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
})
|
||||
|
|
@ -2857,7 +2857,7 @@ func TestExecutor_Execute_Sum(t *testing.T) {
|
|||
t.Run("WithFilter", func(t *testing.T) {
|
||||
if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(Row(x=0), field=dec)`}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &pql.Decimal{Value: 500005, Scale: 3}, Count: 2}) {
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(500005, 3).Clone(), Count: 2}) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
})
|
||||
|
|
@ -2865,7 +2865,7 @@ func TestExecutor_Execute_Sum(t *testing.T) {
|
|||
t.Run("NoFilter", func(t *testing.T) {
|
||||
if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(dec)`}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &pql.Decimal{Value: 700007, Scale: 3}, Count: 3}) {
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(700007, 3).Clone(), Count: 3}) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
})
|
||||
|
|
@ -2873,7 +2873,7 @@ func TestExecutor_Execute_Sum(t *testing.T) {
|
|||
t.Run("WithFilter", func(t *testing.T) {
|
||||
if result, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{Index: "i", Query: `Sum(dec, Row(x=0))`}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: &pql.Decimal{Value: 500005, Scale: 3}, Count: 2}) {
|
||||
} else if !reflect.DeepEqual(result.Results[0], pilosa.ValCount{DecimalVal: pql.NewDecimal(500005, 3).Clone(), Count: 2}) {
|
||||
t.Fatalf("unexpected result: %s", spew.Sdump(result))
|
||||
}
|
||||
})
|
||||
|
|
@ -4036,7 +4036,7 @@ func TestExecutor_Execute_FieldValue(t *testing.T) {
|
|||
} else {
|
||||
switch exp := test.expVal.(type) {
|
||||
case pql.Decimal:
|
||||
if *vc.DecimalVal != exp {
|
||||
if !vc.DecimalVal.EqualTo(exp) {
|
||||
t.Fatalf("test %d on node%d expected pql.Decimal(%s), but got: %s", i, n, exp, vc.DecimalVal)
|
||||
}
|
||||
case int64:
|
||||
|
|
@ -5358,15 +5358,15 @@ func TestExecutor_GroupByStrings(t *testing.T) {
|
|||
{
|
||||
query: "GroupBy(Rows(generals), aggregate=Sum(field=dv))",
|
||||
expected: []pilosa.GroupCount{
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 1, RowKey: "r1"}}, Count: 5, Agg: 2775, DecimalAgg: &pql.Decimal{Value: 2775, Scale: 2}},
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Agg: 3220, DecimalAgg: &pql.Decimal{Value: 3220, Scale: 2}},
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 1, RowKey: "r1"}}, Count: 5, Agg: 2775, DecimalAgg: pql.NewDecimal(2775, 2).Clone()},
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Agg: 3220, DecimalAgg: pql.NewDecimal(3220, 2).Clone()},
|
||||
},
|
||||
},
|
||||
{
|
||||
query: "GroupBy(Rows(generals), aggregate=Sum(field=ndv))",
|
||||
expected: []pilosa.GroupCount{
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 1, RowKey: "r1"}}, Count: 5, Agg: -2775, DecimalAgg: &pql.Decimal{Value: -2775, Scale: 1}},
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Agg: -3220, DecimalAgg: &pql.Decimal{Value: -3220, Scale: 1}},
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 1, RowKey: "r1"}}, Count: 5, Agg: -2775, DecimalAgg: pql.NewDecimal(-2775, 1).Clone()},
|
||||
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Agg: -3220, DecimalAgg: pql.NewDecimal(-3220, 1).Clone()},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -8663,7 +8663,7 @@ func TestToRows(t *testing.T) {
|
|||
if e != nil {
|
||||
t.Fatal("Shouldn't be err ", e)
|
||||
}
|
||||
v.DecimalVal = &pql.Decimal{Value: 1, Scale: 1}
|
||||
v.DecimalVal = pql.NewDecimal(1, 1).Clone()
|
||||
e = v.ToRows(func(*proto.RowResponse) error {
|
||||
return nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -754,29 +754,29 @@ func TestDecimalField_MinMaxForShard(t *testing.T) {
|
|||
name: "single",
|
||||
columnIDs: []uint64{1},
|
||||
values: []float64{10.1},
|
||||
expMax: ValCount{Val: 10100, DecimalVal: &pql.Decimal{Value: 10100, Scale: 3}, Count: 1},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: &pql.Decimal{Value: 10100, Scale: 3}, Count: 1},
|
||||
expMax: ValCount{Val: 10100, DecimalVal: pql.NewDecimal(10100, 3).Clone(), Count: 1},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: pql.NewDecimal(10100, 3).Clone(), Count: 1},
|
||||
},
|
||||
{
|
||||
name: "twovals",
|
||||
columnIDs: []uint64{1, 2},
|
||||
values: []float64{10.1, 20.2},
|
||||
expMax: ValCount{Val: 20200, DecimalVal: &pql.Decimal{Value: 20200, Scale: 3}, Count: 1},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: &pql.Decimal{Value: 10100, Scale: 3}, Count: 1},
|
||||
expMax: ValCount{Val: 20200, DecimalVal: pql.NewDecimal(20200, 3).Clone(), Count: 1},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: pql.NewDecimal(10100, 3).Clone(), Count: 1},
|
||||
},
|
||||
{
|
||||
name: "multiplecounts",
|
||||
columnIDs: []uint64{1, 2, 3, 4, 5},
|
||||
values: []float64{10.1, 20.2, 10.1, 10.1, 20.2},
|
||||
expMax: ValCount{Val: 20200, DecimalVal: &pql.Decimal{Value: 20200, Scale: 3}, Count: 2},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: &pql.Decimal{Value: 10100, Scale: 3}, Count: 3},
|
||||
expMax: ValCount{Val: 20200, DecimalVal: pql.NewDecimal(20200, 3).Clone(), Count: 2},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: pql.NewDecimal(10100, 3).Clone(), Count: 3},
|
||||
},
|
||||
{
|
||||
name: "middlevals",
|
||||
columnIDs: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
values: []float64{10.1, 20.2, 10.1, 10.1, 20.2, 11, 12, 11, 13, 11},
|
||||
expMax: ValCount{Val: 20200, DecimalVal: &pql.Decimal{Value: 20200, Scale: 3}, Count: 2},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: &pql.Decimal{Value: 10100, Scale: 3}, Count: 3},
|
||||
expMax: ValCount{Val: 20200, DecimalVal: pql.NewDecimal(20200, 3).Clone(), Count: 2},
|
||||
expMin: ValCount{Val: 10100, DecimalVal: pql.NewDecimal(10100, 3).Clone(), Count: 3},
|
||||
},
|
||||
} {
|
||||
t.Run(test.name+strconv.Itoa(i), func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -279,10 +279,23 @@ func TestField_ClearValue(t *testing.T) {
|
|||
|
||||
func TestFieldInfoMarshal(t *testing.T) {
|
||||
f := &pilosa.FieldInfo{Name: "timestamp", CreatedAt: 1649270079233541000,
|
||||
Options: pilosa.FieldOptions{Base: 0, BitDepth: 0x0, Min: pql.Decimal{Value: -4294967296,
|
||||
Scale: 0}, Max: pql.Decimal{Value: 4294967296, Scale: 0}, Scale: 0, Keys: false,
|
||||
NoStandardView: false, CacheType: "", Type: "timestamp", TimeUnit: "s",
|
||||
TimeQuantum: "", ForeignIndex: "", TTL: 0}, Cardinality: (*uint64)(nil)}
|
||||
Options: pilosa.FieldOptions{
|
||||
Base: 0,
|
||||
BitDepth: 0x0,
|
||||
Min: pql.NewDecimal(-4294967296, 0),
|
||||
Max: pql.NewDecimal(4294967296, 0),
|
||||
Scale: 0,
|
||||
Keys: false,
|
||||
NoStandardView: false,
|
||||
CacheType: "",
|
||||
Type: "timestamp",
|
||||
TimeUnit: "s",
|
||||
TimeQuantum: "",
|
||||
ForeignIndex: "",
|
||||
TTL: 0,
|
||||
},
|
||||
Cardinality: (*uint64)(nil),
|
||||
}
|
||||
a, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error marshalling index info, %v", err)
|
||||
|
|
|
|||
16
index.go
16
index.go
|
|
@ -4,6 +4,7 @@ package pilosa
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
|
@ -651,12 +652,15 @@ func (i *Index) CreateFieldIfNotExistsWithOptions(name string, opt *FieldOptions
|
|||
if opt != nil && (opt.Type == FieldTypeInt || opt.Type == FieldTypeTimestamp) {
|
||||
min, max := pql.MinMax(0)
|
||||
// ensure the provided bounds are valid
|
||||
if opt.Max.Value == 0 {
|
||||
zero := big.NewInt(0)
|
||||
maxv := opt.Max.Value()
|
||||
if maxv.Cmp(zero) == 0 {
|
||||
opt.Max = max
|
||||
} else if max.LessThan(opt.Max) {
|
||||
opt.Max = max
|
||||
}
|
||||
if opt.Min.Value == 0 {
|
||||
minv := opt.Min.Value()
|
||||
if minv.Cmp(zero) == 0 {
|
||||
opt.Min = min
|
||||
} else if min.GreaterThan(opt.Min) {
|
||||
opt.Min = min
|
||||
|
|
@ -665,14 +669,18 @@ func (i *Index) CreateFieldIfNotExistsWithOptions(name string, opt *FieldOptions
|
|||
// added for backward compatablity with old schemas
|
||||
if opt != nil && opt.Type == FieldTypeDecimal {
|
||||
min, max := pql.MinMax(opt.Scale)
|
||||
zero := big.NewInt(0)
|
||||
|
||||
// ensure the provided bounds are valid
|
||||
if opt.Max.Value == 0 {
|
||||
maxv := opt.Max.Value()
|
||||
if maxv.Cmp(zero) == 0 {
|
||||
opt.Max = max
|
||||
} else if max.LessThan(opt.Max) {
|
||||
opt.Max = max
|
||||
}
|
||||
|
||||
if opt.Min.Value == 0 {
|
||||
minv := opt.Min.Value()
|
||||
if minv.Cmp(zero) == 0 {
|
||||
opt.Min = min
|
||||
} else if min.GreaterThan(opt.Min) {
|
||||
opt.Min = min
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ func TestIndex_CreateField(t *testing.T) {
|
|||
t.Run("DecimalField", func(t *testing.T) {
|
||||
index := test.MustOpenIndex(t)
|
||||
|
||||
_, err := index.CreateField("f", pilosa.OptFieldTypeDecimal(1, pql.Decimal{Value: -1}, pql.Decimal{Value: 1}), pilosa.OptFieldKeys())
|
||||
_, err := index.CreateField("f", pilosa.OptFieldTypeDecimal(1, pql.NewDecimal(-1, 0), pql.NewDecimal(1, 0)), pilosa.OptFieldKeys())
|
||||
if errors.Cause(err) != pilosa.ErrDecimalFieldWithKeys {
|
||||
t.Fatal("decimal field cannot be created with keys=true")
|
||||
}
|
||||
|
|
|
|||
289
pb/public.pb.go
289
pb/public.pb.go
|
|
@ -1243,8 +1243,7 @@ func (m *ValCount) GetTimestampVal() string {
|
|||
}
|
||||
|
||||
type Decimal struct {
|
||||
Value int64 `protobuf:"varint,1,opt,name=Value,proto3" json:"Value,omitempty"`
|
||||
Scale int64 `protobuf:"varint,2,opt,name=Scale,proto3" json:"Scale,omitempty"`
|
||||
Gob []byte `protobuf:"bytes,1,opt,name=Gob,proto3" json:"Gob,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
|
@ -1283,18 +1282,11 @@ func (m *Decimal) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_Decimal proto.InternalMessageInfo
|
||||
|
||||
func (m *Decimal) GetValue() int64 {
|
||||
func (m *Decimal) GetGob() []byte {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
return m.Gob
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Decimal) GetScale() int64 {
|
||||
if m != nil {
|
||||
return m.Scale
|
||||
}
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
|
||||
type DistinctTimestamp struct {
|
||||
|
|
@ -2657,113 +2649,113 @@ func init() {
|
|||
func init() { proto.RegisterFile("public.proto", fileDescriptor_413a91106d7bcce8) }
|
||||
|
||||
var fileDescriptor_413a91106d7bcce8 = []byte{
|
||||
// 1694 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5b, 0x6f, 0x23, 0x49,
|
||||
0x15, 0x4e, 0x5f, 0x7c, 0x3b, 0x76, 0x9c, 0xa4, 0x36, 0xbb, 0xf4, 0x0e, 0x59, 0xe3, 0x6d, 0xa1,
|
||||
0xc5, 0x4b, 0x50, 0x56, 0x18, 0x18, 0xa1, 0x91, 0x60, 0x14, 0xc7, 0x19, 0x62, 0xcd, 0x24, 0x33,
|
||||
0x94, 0x43, 0xe0, 0x61, 0x5e, 0x3a, 0x76, 0xe1, 0x69, 0xd1, 0x76, 0x9b, 0xee, 0xf6, 0x38, 0xf9,
|
||||
0x01, 0x08, 0x7e, 0x02, 0x6f, 0xfc, 0x1a, 0x04, 0x6f, 0xf0, 0xc8, 0x23, 0x1a, 0xde, 0xf8, 0x15,
|
||||
0xe8, 0x9c, 0xaa, 0xea, 0x9b, 0x9d, 0xd1, 0x68, 0xc4, 0x5b, 0x9f, 0x4b, 0x9d, 0xaa, 0xf3, 0x9d,
|
||||
0xab, 0x0d, 0xad, 0xe5, 0xea, 0x36, 0xf0, 0x27, 0x27, 0xcb, 0x28, 0x4c, 0x42, 0x66, 0x2e, 0x6f,
|
||||
0xdd, 0x7b, 0xb0, 0x78, 0xb8, 0x66, 0x0e, 0xd4, 0xce, 0xc2, 0x60, 0x35, 0x5f, 0xc4, 0x8e, 0xd1,
|
||||
0xb5, 0x7a, 0x36, 0xd7, 0x24, 0x63, 0x60, 0x3f, 0x17, 0xf7, 0xb1, 0x63, 0x75, 0xad, 0x5e, 0x83,
|
||||
0xd3, 0x37, 0x6a, 0xf3, 0xd0, 0x8b, 0xfc, 0xc5, 0xcc, 0xb1, 0xbb, 0x46, 0xaf, 0xc5, 0x35, 0xc9,
|
||||
0x0e, 0xa1, 0x32, 0x5a, 0x4c, 0xc5, 0x9d, 0x53, 0xe9, 0x1a, 0xbd, 0x06, 0x97, 0x04, 0x72, 0x9f,
|
||||
0xf9, 0x22, 0x98, 0x3a, 0x55, 0xc9, 0x25, 0xc2, 0xed, 0x41, 0x83, 0x87, 0xeb, 0x4b, 0x2f, 0x89,
|
||||
0xfc, 0x3b, 0xf6, 0x6d, 0xb0, 0x79, 0xb8, 0x96, 0xb7, 0x37, 0xfb, 0xb5, 0x93, 0xe5, 0xed, 0x09,
|
||||
0x0f, 0xd7, 0x9c, 0x98, 0xee, 0x29, 0x34, 0xc6, 0xfe, 0x6c, 0x21, 0xa6, 0xf8, 0xd4, 0xcf, 0xc1,
|
||||
0x7a, 0x15, 0xa2, 0xa2, 0x91, 0x57, 0x44, 0x1e, 0x8a, 0xae, 0xc4, 0xcc, 0x31, 0x4b, 0xa2, 0x2b,
|
||||
0x31, 0x73, 0x7f, 0x0a, 0x6d, 0x1e, 0xae, 0x47, 0x53, 0xb1, 0x48, 0xfc, 0xdf, 0xfa, 0x22, 0x22,
|
||||
0xc7, 0xd2, 0x1b, 0x6d, 0x79, 0x51, 0xea, 0xac, 0x99, 0x39, 0xeb, 0x3e, 0x82, 0xea, 0x68, 0xf8,
|
||||
0xc2, 0x8f, 0x13, 0xb6, 0x0f, 0xd6, 0x68, 0xa8, 0x0f, 0xe0, 0xa7, 0x7b, 0x06, 0x07, 0xe7, 0x77,
|
||||
0x49, 0xe4, 0x4d, 0x12, 0x31, 0x1d, 0x0d, 0x25, 0x64, 0xac, 0x0d, 0xe6, 0x68, 0x48, 0xef, 0xb3,
|
||||
0xb9, 0x39, 0x1a, 0xb2, 0x0e, 0xd8, 0x37, 0x5e, 0x20, 0x8d, 0x36, 0xfb, 0x80, 0xcf, 0x92, 0x06,
|
||||
0x39, 0xf1, 0xdd, 0xd7, 0x05, 0x23, 0x0a, 0x8f, 0xcf, 0xa0, 0x4a, 0x28, 0xc9, 0xeb, 0x1a, 0x5c,
|
||||
0x51, 0xec, 0x9b, 0x2c, 0x50, 0xd2, 0xde, 0xa7, 0x68, 0x6f, 0xe3, 0x11, 0x69, 0xfc, 0xdc, 0x2f,
|
||||
0xa0, 0xf6, 0x5c, 0xdc, 0xd3, 0xfb, 0xb5, 0x77, 0x46, 0xce, 0xbb, 0x7f, 0x18, 0xf0, 0x49, 0x7a,
|
||||
0xfa, 0xda, 0xbb, 0x0d, 0xc4, 0x8d, 0x17, 0xac, 0x04, 0xeb, 0x68, 0x5f, 0x8d, 0xe2, 0x9b, 0x2f,
|
||||
0x76, 0xc8, 0x73, 0xf6, 0x65, 0x8a, 0x14, 0x2a, 0x34, 0x51, 0x41, 0x5d, 0x73, 0xb1, 0xa3, 0xb2,
|
||||
0xe4, 0x08, 0xea, 0x83, 0xf1, 0x88, 0xcc, 0x39, 0x56, 0xd7, 0xe8, 0x59, 0x17, 0x3b, 0x3c, 0xe5,
|
||||
0xb0, 0x47, 0x50, 0xbb, 0x5c, 0x25, 0xe2, 0x6e, 0x34, 0xa4, 0x1c, 0xb2, 0x2f, 0x76, 0xb8, 0x66,
|
||||
0xe0, 0x49, 0xfa, 0x7c, 0x2e, 0xee, 0x65, 0x22, 0xe1, 0x49, 0xcd, 0x61, 0x87, 0x60, 0x0f, 0xc2,
|
||||
0x30, 0xa0, 0x64, 0xaa, 0xe3, 0x6d, 0x48, 0x0d, 0x6a, 0x50, 0x21, 0xc3, 0xee, 0x1d, 0x1c, 0x16,
|
||||
0x1d, 0x52, 0x61, 0x61, 0x60, 0xa1, 0x3d, 0x43, 0xd9, 0x43, 0x82, 0xed, 0x53, 0xa8, 0x4c, 0x75,
|
||||
0x3f, 0x06, 0xeb, 0x1b, 0xa8, 0x92, 0x19, 0x99, 0xf0, 0xcd, 0xfe, 0xb7, 0x0a, 0xf0, 0x66, 0x00,
|
||||
0x71, 0xa5, 0x36, 0x68, 0x10, 0xbe, 0x2f, 0xa3, 0xd1, 0xd0, 0xfd, 0x59, 0x19, 0x4a, 0x8a, 0x19,
|
||||
0xc2, 0x7e, 0xe5, 0xcd, 0x85, 0xbc, 0x99, 0xd3, 0x37, 0xf2, 0xae, 0xef, 0x97, 0x82, 0xae, 0x6e,
|
||||
0x70, 0xfa, 0x76, 0x57, 0xd0, 0x2e, 0x1e, 0xc7, 0xc7, 0xe4, 0x92, 0x60, 0xeb, 0x63, 0x48, 0x9e,
|
||||
0x66, 0x47, 0xbf, 0x9c, 0x1d, 0xce, 0xe6, 0x89, 0x72, 0x82, 0xfc, 0x1c, 0xec, 0x57, 0x9e, 0x1f,
|
||||
0x6d, 0xa4, 0xed, 0xbe, 0xc4, 0xcb, 0xa2, 0x17, 0x5a, 0x12, 0xf8, 0xca, 0x59, 0xb8, 0x5a, 0x24,
|
||||
0x12, 0x30, 0x2e, 0x09, 0xf7, 0x29, 0x34, 0xf0, 0xbc, 0xf4, 0xf5, 0x48, 0x1a, 0x53, 0x79, 0x53,
|
||||
0xc7, 0xdb, 0x91, 0xe6, 0xf2, 0x8a, 0xb4, 0x0f, 0x98, 0xf9, 0x3e, 0x30, 0x00, 0x40, 0x69, 0x2c,
|
||||
0x2d, 0x74, 0xa0, 0x42, 0x94, 0x72, 0x39, 0x33, 0x21, 0xd9, 0x0f, 0xd8, 0xf8, 0x02, 0xfb, 0x4e,
|
||||
0xf2, 0xf8, 0xc7, 0x28, 0x96, 0x19, 0x87, 0x2f, 0xb0, 0xb8, 0xca, 0x89, 0x10, 0xea, 0x12, 0xa8,
|
||||
0x70, 0x9d, 0x19, 0x30, 0x72, 0x06, 0x90, 0x8b, 0xfd, 0x61, 0xa8, 0x7d, 0x23, 0x02, 0xab, 0x90,
|
||||
0x87, 0xeb, 0x0c, 0x06, 0x45, 0xb1, 0xef, 0xe8, 0x5b, 0x6c, 0xf2, 0xb3, 0x41, 0xf5, 0x81, 0xf7,
|
||||
0xeb, 0x0b, 0x7f, 0x03, 0xf0, 0x8b, 0x28, 0x5c, 0x2d, 0x09, 0x22, 0xe6, 0x42, 0x85, 0x28, 0xe5,
|
||||
0x53, 0x0b, 0xd5, 0xf5, 0x7b, 0xb8, 0x14, 0x6d, 0x07, 0x17, 0x83, 0x70, 0x3a, 0x9b, 0xc9, 0xf2,
|
||||
0xe1, 0xf8, 0xe9, 0xfe, 0xc5, 0x80, 0xfa, 0x8d, 0x17, 0xa4, 0xe2, 0x1b, 0x2f, 0x50, 0xbe, 0xe2,
|
||||
0x67, 0xd1, 0x8c, 0xa5, 0xcd, 0x3c, 0x82, 0xfa, 0xb3, 0x20, 0xf4, 0x12, 0x54, 0x46, 0x5b, 0x06,
|
||||
0x4f, 0x69, 0x76, 0x0c, 0x30, 0x14, 0x13, 0x7f, 0xee, 0x05, 0x28, 0xb5, 0xb3, 0x7a, 0x56, 0x5c,
|
||||
0x9e, 0x13, 0x33, 0x17, 0x5a, 0xd7, 0xfe, 0x5c, 0xc4, 0x89, 0x37, 0x5f, 0xa2, 0xba, 0x6c, 0xf3,
|
||||
0x05, 0x9e, 0xfb, 0x13, 0xa8, 0xa9, 0x13, 0xdb, 0xa3, 0x81, 0xdc, 0xf1, 0xc4, 0x0b, 0x84, 0x7e,
|
||||
0x23, 0x11, 0xee, 0x53, 0x38, 0x18, 0xfa, 0x71, 0xe2, 0x2f, 0x26, 0x49, 0x6a, 0x0e, 0x03, 0xa0,
|
||||
0xca, 0x51, 0xb5, 0x41, 0x49, 0xa5, 0x35, 0x65, 0x66, 0x35, 0xe5, 0xfe, 0xd5, 0x80, 0xd6, 0x2f,
|
||||
0x57, 0x22, 0xba, 0xe7, 0xe2, 0xf7, 0x2b, 0x11, 0x27, 0x78, 0x0f, 0xd1, 0x3a, 0xd2, 0x44, 0xa0,
|
||||
0xc9, 0xf1, 0x1b, 0x2f, 0x9a, 0xca, 0x12, 0xb1, 0xb9, 0xa2, 0x28, 0xd6, 0x62, 0x1e, 0x26, 0x82,
|
||||
0x9c, 0xaa, 0x73, 0x45, 0xb1, 0x63, 0x68, 0x9d, 0xcf, 0x6f, 0xc5, 0x74, 0x2a, 0xa6, 0x43, 0x2f,
|
||||
0xf1, 0x9c, 0x7a, 0x71, 0x42, 0x15, 0x84, 0xec, 0xbb, 0xb0, 0xfb, 0x2a, 0x12, 0xd7, 0x91, 0xb7,
|
||||
0x88, 0x03, 0x2f, 0x11, 0x53, 0xa7, 0x41, 0xb6, 0x8a, 0x4c, 0x76, 0x04, 0x8d, 0x4b, 0xef, 0xee,
|
||||
0x52, 0xcc, 0xc3, 0xe8, 0xde, 0x01, 0x02, 0x21, 0x63, 0xb8, 0x2f, 0x60, 0x57, 0xb9, 0x11, 0x2f,
|
||||
0xc3, 0x45, 0x2c, 0x30, 0xca, 0xe7, 0x51, 0xa4, 0xbc, 0xc0, 0x4f, 0xf6, 0x35, 0xd4, 0xb8, 0x88,
|
||||
0x57, 0x41, 0xa2, 0xeb, 0x7c, 0x0f, 0x9f, 0xa3, 0x4f, 0xad, 0x82, 0x84, 0x6b, 0xb9, 0xfb, 0xdf,
|
||||
0x0a, 0x34, 0x73, 0x82, 0xb4, 0xf3, 0x60, 0xf7, 0xdc, 0x95, 0x9d, 0x07, 0xe7, 0x26, 0x0f, 0xd7,
|
||||
0x1b, 0x23, 0x15, 0xab, 0xa5, 0x05, 0xc6, 0x95, 0x4a, 0x49, 0xe3, 0x2a, 0x2b, 0x4e, 0x6b, 0x7b,
|
||||
0x71, 0xe2, 0x1a, 0xf1, 0xc6, 0x5b, 0xcc, 0xc4, 0x94, 0x12, 0xa9, 0xce, 0x35, 0xc9, 0x7a, 0x59,
|
||||
0xd6, 0x12, 0xbe, 0xaa, 0x0a, 0x34, 0x8f, 0x67, 0x39, 0x2d, 0x6b, 0x0e, 0x87, 0x4f, 0x4d, 0xc6,
|
||||
0x47, 0x52, 0xec, 0x31, 0xb4, 0x5f, 0x06, 0xd3, 0xac, 0xaa, 0x62, 0x15, 0x89, 0x36, 0xda, 0xc9,
|
||||
0xd8, 0xbc, 0xa4, 0xc5, 0x9e, 0x94, 0x27, 0x3f, 0xc5, 0xa4, 0xd9, 0x67, 0xca, 0xcf, 0x9c, 0x84,
|
||||
0x97, 0x77, 0x84, 0xe3, 0xdc, 0xe2, 0x41, 0x81, 0x6a, 0xf6, 0x77, 0xf1, 0x58, 0xca, 0xe4, 0xb9,
|
||||
0xc5, 0xe4, 0x24, 0xdf, 0xc7, 0x9c, 0x26, 0x69, 0xb7, 0x35, 0x42, 0x92, 0xcb, 0xf3, 0x9d, 0xee,
|
||||
0x38, 0xd7, 0x38, 0x9d, 0x56, 0x66, 0x3c, 0x65, 0xf2, 0x5c, 0x63, 0x3d, 0xdb, 0xb2, 0x24, 0x38,
|
||||
0xbb, 0x74, 0xa8, 0xbc, 0x01, 0x48, 0x21, 0xdf, 0xb2, 0x54, 0x3c, 0x29, 0x4f, 0x18, 0xa7, 0x9d,
|
||||
0x41, 0x51, 0x94, 0xf0, 0xf2, 0x2c, 0x3a, 0xce, 0x6d, 0x6b, 0xce, 0x5e, 0xf6, 0xda, 0x94, 0xc9,
|
||||
0x73, 0xdb, 0xdc, 0x0f, 0xa1, 0x99, 0x0f, 0xd4, 0x3e, 0xa9, 0xef, 0x15, 0x03, 0x15, 0xf3, 0xbc,
|
||||
0x0e, 0x3a, 0xb8, 0x51, 0xfe, 0xce, 0x41, 0xe6, 0xe0, 0x86, 0x90, 0x6f, 0xea, 0xbb, 0x7f, 0x33,
|
||||
0x61, 0x77, 0x34, 0x5f, 0x86, 0x51, 0x92, 0xeb, 0x01, 0x72, 0x21, 0x35, 0xb6, 0x2e, 0xa4, 0x66,
|
||||
0x69, 0x06, 0x50, 0x2f, 0xa0, 0x16, 0x69, 0x73, 0x49, 0xe4, 0xf2, 0xd1, 0x2e, 0xe4, 0xe3, 0x11,
|
||||
0x34, 0xe4, 0x08, 0x45, 0x51, 0x85, 0x44, 0x19, 0x43, 0xae, 0xc8, 0x6b, 0x5a, 0x91, 0x6a, 0xd4,
|
||||
0xb9, 0x34, 0xc9, 0x3a, 0x00, 0x52, 0x8d, 0x84, 0x75, 0x12, 0xe6, 0x38, 0x28, 0x4f, 0x1d, 0x8a,
|
||||
0x9d, 0x6a, 0xd7, 0xea, 0x59, 0x3c, 0xc7, 0x61, 0x5f, 0x41, 0x9b, 0x9c, 0x38, 0x8b, 0x04, 0x36,
|
||||
0x93, 0xd3, 0x84, 0xf2, 0xd9, 0xe2, 0x25, 0x2e, 0xea, 0x91, 0x5b, 0x99, 0x9e, 0xec, 0x34, 0x25,
|
||||
0x2e, 0x4d, 0x8c, 0x40, 0x78, 0x11, 0x65, 0x6c, 0x9d, 0x4b, 0xc2, 0xfd, 0x97, 0x09, 0x4c, 0x22,
|
||||
0x29, 0xd7, 0x9d, 0xff, 0x1b, 0x9c, 0xef, 0x87, 0xad, 0x08, 0x4e, 0x6d, 0x03, 0x9c, 0x6c, 0x1e,
|
||||
0x48, 0x60, 0xf4, 0x3c, 0xe8, 0x42, 0x53, 0x0f, 0x34, 0x14, 0x22, 0xaa, 0x06, 0xcf, 0xb3, 0x70,
|
||||
0x72, 0x8d, 0x13, 0xfc, 0x8d, 0xa2, 0x54, 0x1a, 0x64, 0xbb, 0xc0, 0xdb, 0x02, 0x2d, 0x7c, 0x20,
|
||||
0xb4, 0xcd, 0xf7, 0x43, 0xdb, 0xca, 0x43, 0xfb, 0x47, 0x03, 0x5a, 0xa7, 0x49, 0x38, 0xf7, 0x27,
|
||||
0x5c, 0x4c, 0xc2, 0x68, 0xfa, 0x30, 0xa8, 0x12, 0x3e, 0x33, 0x0f, 0x5f, 0x0f, 0xac, 0xd1, 0xdb,
|
||||
0x48, 0xf5, 0xdf, 0xcf, 0x68, 0xef, 0xd8, 0x88, 0x12, 0x47, 0x15, 0xf6, 0x25, 0x98, 0xa3, 0x88,
|
||||
0x72, 0xb6, 0xd9, 0x3f, 0xc8, 0x14, 0xb5, 0x8e, 0x39, 0x8a, 0xdc, 0x1f, 0xc0, 0xa1, 0x7c, 0x88,
|
||||
0x16, 0xa9, 0x81, 0x73, 0x08, 0x95, 0xf3, 0x28, 0x0a, 0xf5, 0xc8, 0x91, 0x04, 0x2e, 0xd6, 0xe9,
|
||||
0x0c, 0xc3, 0x60, 0x7c, 0x4c, 0x4e, 0x6c, 0xfb, 0x35, 0xd9, 0x85, 0xe6, 0x55, 0x98, 0xfc, 0x3a,
|
||||
0xf2, 0x13, 0x6a, 0x49, 0x72, 0x70, 0xe4, 0x59, 0xee, 0xd7, 0xf0, 0x69, 0xe9, 0xe6, 0x6c, 0x32,
|
||||
0x62, 0x1a, 0x59, 0xd9, 0x2f, 0xb2, 0x31, 0x7c, 0x92, 0xaa, 0x8e, 0x86, 0x1f, 0xf5, 0xc6, 0x4d,
|
||||
0xa3, 0xdf, 0xcf, 0x79, 0x4e, 0x46, 0xd5, 0xf5, 0x5b, 0xbc, 0x71, 0x07, 0xe0, 0x28, 0x34, 0xe5,
|
||||
0x4f, 0x62, 0xf5, 0x82, 0x1b, 0x5f, 0xac, 0x1f, 0xfa, 0x25, 0x40, 0x6b, 0x85, 0x49, 0x3f, 0xa4,
|
||||
0xe9, 0xdb, 0xfd, 0x93, 0x09, 0x87, 0xdb, 0x8c, 0x64, 0x09, 0x65, 0xe4, 0x12, 0x8a, 0xf5, 0xa1,
|
||||
0xf2, 0xd6, 0x17, 0x6b, 0xbd, 0x0b, 0x1c, 0xe5, 0x82, 0xbd, 0xf1, 0x06, 0x2e, 0x55, 0xb1, 0x90,
|
||||
0x4e, 0x27, 0x89, 0x1f, 0x2e, 0xf4, 0x66, 0x2b, 0x29, 0xbc, 0x61, 0x10, 0x84, 0x93, 0xdf, 0xc9,
|
||||
0x1f, 0x65, 0x5c, 0x12, 0x5b, 0x0a, 0xa3, 0xf2, 0x81, 0x85, 0x51, 0xdd, 0x5a, 0x18, 0x3d, 0xd8,
|
||||
0xfb, 0xd5, 0x72, 0xea, 0x25, 0xe2, 0xfc, 0xce, 0x8f, 0x13, 0xb1, 0x98, 0x08, 0xa7, 0x46, 0x1e,
|
||||
0x95, 0xd9, 0xee, 0x1f, 0x0c, 0xd8, 0x55, 0x5e, 0x48, 0xd1, 0x03, 0xfb, 0x3b, 0x03, 0x1b, 0xdd,
|
||||
0xd3, 0x0b, 0x21, 0xc1, 0x9d, 0xa2, 0x65, 0x11, 0xb6, 0x0a, 0xad, 0x7d, 0xb0, 0xc6, 0x22, 0x51,
|
||||
0x7f, 0x5c, 0xe0, 0x27, 0xb6, 0x06, 0x12, 0xc9, 0x72, 0x8c, 0xd5, 0xfe, 0x57, 0xe0, 0xb9, 0xaf,
|
||||
0xe1, 0xf3, 0x02, 0xa4, 0x54, 0x8d, 0x3a, 0x2c, 0xd9, 0xea, 0x68, 0x14, 0x56, 0xc7, 0xef, 0x41,
|
||||
0xe5, 0x26, 0x17, 0x98, 0x03, 0x39, 0x2f, 0x73, 0xce, 0x70, 0x29, 0x77, 0xc7, 0x85, 0x79, 0x89,
|
||||
0x3d, 0xf2, 0x74, 0x36, 0x8b, 0xc4, 0xcc, 0x4b, 0x74, 0xb2, 0x64, 0x0c, 0xf6, 0x15, 0x54, 0x49,
|
||||
0x59, 0x9b, 0x2d, 0x2f, 0x40, 0x4a, 0x3a, 0xd8, 0xff, 0xfb, 0xbb, 0x8e, 0xf1, 0xcf, 0x77, 0x1d,
|
||||
0xe3, 0xdf, 0xef, 0x3a, 0xc6, 0x9f, 0xff, 0xd3, 0xd9, 0xb9, 0xad, 0xd2, 0xff, 0x3e, 0x3f, 0xfa,
|
||||
0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x84, 0x6e, 0xe4, 0x07, 0x12, 0x00, 0x00,
|
||||
// 1692 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4b, 0x6f, 0x1b, 0xd7,
|
||||
0x15, 0xd6, 0x3c, 0xf8, 0x3a, 0xa4, 0x28, 0xe9, 0x5a, 0x76, 0xc7, 0xb6, 0xcc, 0xd2, 0x83, 0xc2,
|
||||
0xa5, 0xab, 0x42, 0x46, 0xd9, 0xc2, 0x28, 0x0c, 0xb4, 0x86, 0x28, 0xca, 0x16, 0x61, 0x4b, 0x76,
|
||||
0xaf, 0x54, 0xb5, 0x0b, 0x6f, 0x46, 0xe4, 0x2d, 0x3d, 0xe8, 0x90, 0xc3, 0xcc, 0x0c, 0x4d, 0xe9,
|
||||
0x07, 0x04, 0xc9, 0x4f, 0xc8, 0x2e, 0xbf, 0x26, 0x48, 0x76, 0xc9, 0x32, 0xcb, 0xc0, 0xd9, 0xe5,
|
||||
0x57, 0x04, 0xe7, 0xdc, 0x3b, 0x4f, 0x52, 0x86, 0x61, 0x64, 0x37, 0xe7, 0x71, 0xcf, 0xbd, 0xe7,
|
||||
0x3b, 0x4f, 0x12, 0x1a, 0xb3, 0xf9, 0x85, 0xe7, 0x0e, 0xf7, 0x66, 0x81, 0x1f, 0xf9, 0x4c, 0x9f,
|
||||
0x5d, 0xd8, 0x57, 0x60, 0x70, 0x7f, 0xc1, 0x2c, 0xa8, 0x1c, 0xf8, 0xde, 0x7c, 0x32, 0x0d, 0x2d,
|
||||
0xad, 0x6d, 0x74, 0x4c, 0x1e, 0x93, 0x8c, 0x81, 0xf9, 0x42, 0x5c, 0x85, 0x96, 0xd1, 0x36, 0x3a,
|
||||
0x35, 0x4e, 0xdf, 0xa8, 0xcd, 0x7d, 0x27, 0x70, 0xa7, 0x63, 0xcb, 0x6c, 0x6b, 0x9d, 0x06, 0x8f,
|
||||
0x49, 0xb6, 0x0d, 0xa5, 0xc1, 0x74, 0x24, 0x2e, 0xad, 0x52, 0x5b, 0xeb, 0xd4, 0xb8, 0x24, 0x90,
|
||||
0xfb, 0xcc, 0x15, 0xde, 0xc8, 0x2a, 0x4b, 0x2e, 0x11, 0x76, 0x07, 0x6a, 0xdc, 0x5f, 0x1c, 0x3b,
|
||||
0x51, 0xe0, 0x5e, 0xb2, 0xbb, 0x60, 0x72, 0x7f, 0x21, 0x6f, 0xaf, 0x77, 0x2b, 0x7b, 0xb3, 0x8b,
|
||||
0x3d, 0xee, 0x2f, 0x38, 0x31, 0xed, 0x7d, 0xa8, 0x9d, 0xba, 0xe3, 0xa9, 0x18, 0xe1, 0x53, 0x6f,
|
||||
0x83, 0xf1, 0xda, 0x47, 0x45, 0x2d, 0xab, 0x88, 0x3c, 0x14, 0x9d, 0x88, 0xb1, 0xa5, 0x17, 0x44,
|
||||
0x27, 0x62, 0x6c, 0xff, 0x1d, 0x9a, 0xdc, 0x5f, 0x0c, 0x46, 0x62, 0x1a, 0xb9, 0xff, 0x73, 0x45,
|
||||
0x40, 0x8e, 0x25, 0x37, 0x9a, 0xf2, 0xa2, 0xc4, 0x59, 0x3d, 0x75, 0xd6, 0xbe, 0x03, 0xe5, 0x41,
|
||||
0xff, 0xa5, 0x1b, 0x46, 0x6c, 0x13, 0x8c, 0x41, 0x3f, 0x3e, 0x80, 0x9f, 0xf6, 0x01, 0x6c, 0x1d,
|
||||
0x5e, 0x46, 0x81, 0x33, 0x8c, 0xc4, 0x68, 0xd0, 0x97, 0x90, 0xb1, 0x26, 0xe8, 0x83, 0x3e, 0xbd,
|
||||
0xcf, 0xe4, 0xfa, 0xa0, 0xcf, 0x5a, 0x60, 0x9e, 0x3b, 0x9e, 0x34, 0x5a, 0xef, 0x02, 0x3e, 0x4b,
|
||||
0x1a, 0xe4, 0xc4, 0xb7, 0xdf, 0xe4, 0x8c, 0x28, 0x3c, 0x6e, 0x41, 0x99, 0x50, 0x92, 0xd7, 0xd5,
|
||||
0xb8, 0xa2, 0xd8, 0xa3, 0x34, 0x50, 0xd2, 0xde, 0x4d, 0xb4, 0xb7, 0xf4, 0x88, 0x24, 0x7e, 0xf6,
|
||||
0x3d, 0xa8, 0xbc, 0x10, 0x57, 0xf4, 0xfe, 0xd8, 0x3b, 0x2d, 0xe3, 0xdd, 0xf7, 0x1a, 0xdc, 0x48,
|
||||
0x4e, 0x9f, 0x39, 0x17, 0x9e, 0x38, 0x77, 0xbc, 0xb9, 0x60, 0xad, 0xd8, 0x57, 0x2d, 0xff, 0xe6,
|
||||
0xa3, 0x35, 0xf2, 0x9c, 0xdd, 0x4f, 0x90, 0x42, 0x85, 0x3a, 0x2a, 0xa8, 0x6b, 0x8e, 0xd6, 0x54,
|
||||
0x96, 0xec, 0x40, 0xb5, 0x77, 0x3a, 0x20, 0x73, 0x96, 0xd1, 0xd6, 0x3a, 0xc6, 0xd1, 0x1a, 0x4f,
|
||||
0x38, 0xec, 0x0e, 0x54, 0x8e, 0xe7, 0x91, 0xb8, 0x1c, 0xf4, 0x29, 0x87, 0xcc, 0xa3, 0x35, 0x1e,
|
||||
0x33, 0xf0, 0x24, 0x7d, 0xbe, 0x10, 0x57, 0x32, 0x91, 0xf0, 0x64, 0xcc, 0x61, 0xdb, 0x60, 0xf6,
|
||||
0x7c, 0xdf, 0xa3, 0x64, 0xaa, 0xe2, 0x6d, 0x48, 0xf5, 0x2a, 0x50, 0x22, 0xc3, 0xf6, 0x25, 0x6c,
|
||||
0xe7, 0x1d, 0x52, 0x61, 0x61, 0x60, 0xa0, 0x3d, 0x4d, 0xd9, 0x43, 0x82, 0x6d, 0x52, 0xa8, 0x74,
|
||||
0x75, 0x3f, 0x06, 0xeb, 0x11, 0x94, 0xc9, 0x8c, 0x4c, 0xf8, 0x7a, 0xf7, 0x77, 0x39, 0x78, 0x53,
|
||||
0x80, 0xb8, 0x52, 0xeb, 0xd5, 0x08, 0xdf, 0x57, 0xc1, 0xa0, 0x6f, 0xff, 0xa3, 0x08, 0x25, 0xc5,
|
||||
0x0c, 0x61, 0x3f, 0x71, 0x26, 0x42, 0xde, 0xcc, 0xe9, 0x1b, 0x79, 0x67, 0x57, 0x33, 0x41, 0x57,
|
||||
0xd7, 0x38, 0x7d, 0xdb, 0x73, 0x68, 0xe6, 0x8f, 0xe3, 0x63, 0x32, 0x49, 0xb0, 0xf2, 0x31, 0x24,
|
||||
0x4f, 0xb2, 0xa3, 0x5b, 0xcc, 0x0e, 0x6b, 0xf9, 0x44, 0x31, 0x41, 0xfe, 0x09, 0xe6, 0x6b, 0xc7,
|
||||
0x0d, 0x96, 0xd2, 0x76, 0x53, 0xe2, 0x65, 0xd0, 0x0b, 0x0d, 0x09, 0x7c, 0xe9, 0xc0, 0x9f, 0x4f,
|
||||
0x23, 0x09, 0x18, 0x97, 0x84, 0xfd, 0x14, 0x6a, 0x78, 0x5e, 0xfa, 0xba, 0x23, 0x8d, 0xa9, 0xbc,
|
||||
0xa9, 0xe2, 0xed, 0x48, 0x73, 0x79, 0x45, 0xd2, 0x07, 0xf4, 0x6c, 0x1f, 0xe8, 0x01, 0xa0, 0x34,
|
||||
0x94, 0x16, 0x5a, 0x50, 0x22, 0x4a, 0xb9, 0x9c, 0x9a, 0x90, 0xec, 0x6b, 0x6c, 0xdc, 0xc3, 0xbe,
|
||||
0x13, 0x3d, 0xfe, 0x1b, 0x8a, 0x65, 0xc6, 0xe1, 0x0b, 0x0c, 0xae, 0x72, 0xc2, 0x87, 0xaa, 0x04,
|
||||
0xca, 0x5f, 0xa4, 0x06, 0xb4, 0x8c, 0x01, 0xe4, 0x62, 0x7f, 0xe8, 0xc7, 0xbe, 0x11, 0x81, 0x55,
|
||||
0xc8, 0xfd, 0x45, 0x0a, 0x83, 0xa2, 0xd8, 0xef, 0xe3, 0x5b, 0x4c, 0xf2, 0xb3, 0x46, 0xf5, 0x81,
|
||||
0xf7, 0xc7, 0x17, 0xfe, 0x17, 0xe0, 0x79, 0xe0, 0xcf, 0x67, 0x04, 0x11, 0xb3, 0xa1, 0x44, 0x94,
|
||||
0xf2, 0xa9, 0x81, 0xea, 0xf1, 0x7b, 0xb8, 0x14, 0xad, 0x06, 0x17, 0x83, 0xb0, 0x3f, 0x1e, 0xcb,
|
||||
0xf2, 0xe1, 0xf8, 0x69, 0x7f, 0xad, 0x41, 0xf5, 0xdc, 0xf1, 0x12, 0xf1, 0xb9, 0xe3, 0x29, 0x5f,
|
||||
0xf1, 0x33, 0x6f, 0xc6, 0x88, 0xcd, 0xdc, 0x81, 0xea, 0x33, 0xcf, 0x77, 0x22, 0x54, 0x46, 0x5b,
|
||||
0x1a, 0x4f, 0x68, 0xb6, 0x0b, 0xd0, 0x17, 0x43, 0x77, 0xe2, 0x78, 0x28, 0x35, 0xd3, 0x7a, 0x56,
|
||||
0x5c, 0x9e, 0x11, 0x33, 0x1b, 0x1a, 0x67, 0xee, 0x44, 0x84, 0x91, 0x33, 0x99, 0xa1, 0xba, 0x6c,
|
||||
0xf3, 0x39, 0x9e, 0x7d, 0x17, 0x2a, 0xea, 0x04, 0xbe, 0xef, 0xb9, 0x7f, 0x41, 0xef, 0x6b, 0x70,
|
||||
0xfc, 0xb4, 0x9f, 0xc2, 0x56, 0xdf, 0x0d, 0x23, 0x77, 0x3a, 0x8c, 0x92, 0x43, 0x08, 0xb3, 0x2a,
|
||||
0x3a, 0xd5, 0xec, 0x24, 0x95, 0x54, 0x8e, 0x9e, 0x56, 0x8e, 0xfd, 0x8d, 0x06, 0x8d, 0x7f, 0xcd,
|
||||
0x45, 0x70, 0xc5, 0xc5, 0x67, 0x73, 0x11, 0x46, 0xe8, 0x31, 0xd1, 0x71, 0x3c, 0x89, 0x40, 0x93,
|
||||
0xa7, 0x6f, 0x9d, 0x60, 0x24, 0x0b, 0xc1, 0xe4, 0x8a, 0xa2, 0x88, 0x8a, 0x89, 0x1f, 0x09, 0x7a,
|
||||
0x7a, 0x95, 0x2b, 0x8a, 0xed, 0x42, 0xe3, 0x70, 0x72, 0x21, 0x46, 0x23, 0x31, 0xea, 0x3b, 0x91,
|
||||
0x63, 0x55, 0xf3, 0x73, 0x28, 0x27, 0x64, 0x7f, 0x80, 0xf5, 0xd7, 0x81, 0x38, 0x0b, 0x9c, 0x69,
|
||||
0xe8, 0x39, 0x91, 0x18, 0x59, 0x35, 0xb2, 0x95, 0x67, 0xb2, 0x1d, 0xa8, 0x1d, 0x3b, 0x97, 0xc7,
|
||||
0x62, 0xe2, 0x07, 0x57, 0x16, 0x50, 0x38, 0x52, 0x86, 0xfd, 0x12, 0xd6, 0x95, 0x1b, 0xe1, 0xcc,
|
||||
0x9f, 0x86, 0x02, 0xb1, 0x3a, 0x0c, 0x02, 0xe5, 0x05, 0x7e, 0xb2, 0x87, 0x50, 0xe1, 0x22, 0x9c,
|
||||
0x7b, 0x51, 0x5c, 0xcd, 0x1b, 0xf8, 0x9c, 0xf8, 0xd4, 0xdc, 0x8b, 0x78, 0x2c, 0xb7, 0x7f, 0x29,
|
||||
0x41, 0x3d, 0x23, 0x48, 0xfa, 0x0b, 0xf6, 0xc8, 0x75, 0xd9, 0x5f, 0x70, 0x3a, 0x72, 0x7f, 0xb1,
|
||||
0x34, 0x38, 0xb1, 0x26, 0x1a, 0xa0, 0x9d, 0xa8, 0xc4, 0xd3, 0x4e, 0xd2, 0x12, 0x34, 0x56, 0x97,
|
||||
0x20, 0x2e, 0x0b, 0x6f, 0x9d, 0xe9, 0x58, 0x8c, 0x28, 0x5d, 0xaa, 0x3c, 0x26, 0x59, 0x27, 0xcd,
|
||||
0x4d, 0xc2, 0x57, 0xe5, 0x7a, 0xcc, 0xe3, 0x69, 0xe6, 0xca, 0xca, 0xc2, 0x11, 0x53, 0x91, 0xf1,
|
||||
0x91, 0x14, 0x7b, 0x0c, 0xcd, 0x57, 0xde, 0x28, 0xad, 0x9d, 0x50, 0x45, 0xa2, 0x89, 0x76, 0x52,
|
||||
0x36, 0x2f, 0x68, 0xb1, 0x27, 0xc5, 0xf9, 0x4e, 0x31, 0xa9, 0x77, 0x99, 0xf2, 0x33, 0x23, 0xe1,
|
||||
0xc5, 0x4d, 0x60, 0x37, 0xb3, 0x5e, 0x50, 0xa0, 0xea, 0xdd, 0x75, 0x3c, 0x96, 0x30, 0x79, 0x66,
|
||||
0xfd, 0xd8, 0xcb, 0x76, 0x2b, 0xab, 0x4e, 0xda, 0xcd, 0x18, 0x21, 0xc9, 0xe5, 0xd9, 0x7e, 0xb6,
|
||||
0x9b, 0x69, 0x8f, 0x56, 0x23, 0x35, 0x9e, 0x30, 0x79, 0xa6, 0x7d, 0x1e, 0xac, 0x58, 0x05, 0xac,
|
||||
0x75, 0x3a, 0x54, 0x9c, 0xf3, 0x52, 0xc8, 0x57, 0xac, 0x0e, 0x4f, 0x8a, 0x73, 0xc4, 0x6a, 0xa6,
|
||||
0x50, 0xe4, 0x25, 0xbc, 0x38, 0x71, 0x76, 0x33, 0x3b, 0x99, 0xb5, 0x91, 0xbe, 0x36, 0x61, 0xf2,
|
||||
0xcc, 0xce, 0xf6, 0x17, 0xa8, 0x67, 0x03, 0xb5, 0x49, 0xea, 0x1b, 0xf9, 0x40, 0x85, 0x3c, 0xab,
|
||||
0x83, 0x0e, 0x2e, 0x95, 0xbf, 0xb5, 0x95, 0x3a, 0xb8, 0x24, 0xe4, 0xcb, 0xfa, 0xf6, 0xb7, 0x3a,
|
||||
0xac, 0x0f, 0x26, 0x33, 0x3f, 0x88, 0x32, 0x3d, 0x40, 0xae, 0x9d, 0xda, 0xca, 0xb5, 0x53, 0x2f,
|
||||
0x74, 0x7a, 0xea, 0x05, 0xd4, 0x08, 0x4d, 0x2e, 0x89, 0x4c, 0x3e, 0x9a, 0xb9, 0x7c, 0xdc, 0x81,
|
||||
0x9a, 0x1c, 0x94, 0x28, 0x2a, 0x91, 0x28, 0x65, 0xc8, 0x45, 0x78, 0x41, 0x8b, 0x50, 0x85, 0x3a,
|
||||
0x57, 0x4c, 0xb2, 0x16, 0x80, 0x54, 0x23, 0x61, 0x95, 0x84, 0x19, 0x0e, 0xca, 0x13, 0x87, 0x42,
|
||||
0xab, 0xdc, 0x36, 0x3a, 0x06, 0xcf, 0x70, 0xd8, 0x03, 0x68, 0x92, 0x13, 0x07, 0x81, 0xc0, 0x66,
|
||||
0xb2, 0x1f, 0x51, 0x3e, 0x1b, 0xbc, 0xc0, 0x45, 0x3d, 0x72, 0x2b, 0xd5, 0x93, 0x9d, 0xa6, 0xc0,
|
||||
0xa5, 0xb9, 0xe0, 0x09, 0x27, 0xa0, 0x8c, 0xad, 0x72, 0x49, 0xd8, 0x3f, 0xea, 0xc0, 0x24, 0x92,
|
||||
0x72, 0xa9, 0xf9, 0xcd, 0xe0, 0xfc, 0x30, 0x6c, 0x79, 0x70, 0x2a, 0x4b, 0xe0, 0xa4, 0xf3, 0x40,
|
||||
0x02, 0x13, 0xcf, 0x83, 0x36, 0xd4, 0xe3, 0xb1, 0x85, 0x42, 0x44, 0x55, 0xe3, 0x59, 0x16, 0xce,
|
||||
0xa7, 0xd3, 0x08, 0x7f, 0x89, 0x28, 0x95, 0x1a, 0xd9, 0xce, 0xf1, 0x56, 0x40, 0x0b, 0x1f, 0x09,
|
||||
0x6d, 0xfd, 0xc3, 0xd0, 0x36, 0xb2, 0xd0, 0x7e, 0xa1, 0x41, 0x63, 0x3f, 0xf2, 0x27, 0xee, 0x90,
|
||||
0x8b, 0xa1, 0x1f, 0x8c, 0xae, 0x07, 0x55, 0xc2, 0xa7, 0x67, 0xe1, 0xeb, 0x80, 0x31, 0x78, 0x17,
|
||||
0xa8, 0xfe, 0x7b, 0x8b, 0xb6, 0x8b, 0xa5, 0x28, 0x71, 0x54, 0x61, 0xf7, 0x41, 0x1f, 0x04, 0x94,
|
||||
0xb3, 0xf5, 0xee, 0x56, 0xaa, 0x18, 0xeb, 0xe8, 0x83, 0xc0, 0xfe, 0x33, 0x6c, 0xcb, 0x87, 0xc4,
|
||||
0x22, 0x35, 0x70, 0xb6, 0xa1, 0x74, 0x18, 0x04, 0x7e, 0x3c, 0x72, 0x24, 0x81, 0xeb, 0x73, 0x32,
|
||||
0xc3, 0x30, 0x18, 0x9f, 0x92, 0x13, 0xab, 0x7e, 0x33, 0xb6, 0xa1, 0x7e, 0xe2, 0x47, 0xff, 0x09,
|
||||
0xdc, 0x88, 0x5a, 0x92, 0x1c, 0x1c, 0x59, 0x96, 0xfd, 0x10, 0x6e, 0x16, 0x6e, 0x4e, 0x27, 0x23,
|
||||
0xa6, 0x91, 0x91, 0xfe, 0xee, 0x3a, 0x85, 0x1b, 0x89, 0xea, 0xa0, 0xff, 0x49, 0x6f, 0x5c, 0x36,
|
||||
0xfa, 0xa7, 0x8c, 0xe7, 0x64, 0x54, 0x5d, 0xbf, 0xc2, 0x1b, 0xbb, 0x07, 0x96, 0x42, 0x53, 0xfe,
|
||||
0xf0, 0x55, 0x2f, 0x38, 0x77, 0xc5, 0xe2, 0xba, 0x7d, 0x9f, 0xd6, 0x0a, 0x9d, 0x36, 0x21, 0xfa,
|
||||
0xb6, 0xbf, 0xd4, 0x61, 0x7b, 0x95, 0x91, 0x34, 0xa1, 0xb4, 0x4c, 0x42, 0xb1, 0x2e, 0x94, 0xde,
|
||||
0xb9, 0x62, 0x11, 0xef, 0x02, 0x3b, 0x99, 0x60, 0x2f, 0xbd, 0x81, 0x4b, 0x55, 0x2c, 0xa4, 0xfd,
|
||||
0x61, 0xe4, 0xfa, 0xd3, 0x78, 0x7f, 0x95, 0x14, 0xde, 0xd0, 0xf3, 0xfc, 0xe1, 0xff, 0xe5, 0x4f,
|
||||
0x2f, 0x2e, 0x89, 0x15, 0x85, 0x51, 0xfa, 0xc8, 0xc2, 0x28, 0xaf, 0x2c, 0x8c, 0x0e, 0x6c, 0xfc,
|
||||
0x7b, 0x36, 0x72, 0x22, 0x71, 0x78, 0xe9, 0x86, 0x91, 0x98, 0x0e, 0x85, 0x55, 0x21, 0x8f, 0x8a,
|
||||
0x6c, 0xfb, 0x73, 0x0d, 0xd6, 0x95, 0x17, 0x52, 0x74, 0xcd, 0x96, 0xce, 0xc0, 0x44, 0xf7, 0xe2,
|
||||
0x85, 0x90, 0xe0, 0x4e, 0xd0, 0x32, 0x08, 0x5b, 0x85, 0xd6, 0x26, 0x18, 0xa7, 0x22, 0x52, 0x7f,
|
||||
0x4f, 0xe0, 0x27, 0xb6, 0x06, 0x12, 0xc9, 0x72, 0x0c, 0xd5, 0xfe, 0x97, 0xe3, 0xd9, 0x6f, 0xe0,
|
||||
0x76, 0x0e, 0x52, 0xaa, 0xc6, 0x38, 0x2c, 0xe9, 0xea, 0xa8, 0xe5, 0x56, 0xc7, 0x3f, 0x42, 0xe9,
|
||||
0x3c, 0x13, 0x98, 0x2d, 0x39, 0x2f, 0x33, 0xce, 0x70, 0x29, 0xb7, 0x4f, 0x73, 0xf3, 0x12, 0x7b,
|
||||
0xe4, 0xfe, 0x78, 0x1c, 0x88, 0xb1, 0x13, 0xc5, 0xc9, 0x92, 0x32, 0xd8, 0x03, 0x28, 0x93, 0x72,
|
||||
0x6c, 0xb6, 0xb8, 0x00, 0x29, 0x69, 0x6f, 0xf3, 0xbb, 0xf7, 0x2d, 0xed, 0x87, 0xf7, 0x2d, 0xed,
|
||||
0xa7, 0xf7, 0x2d, 0xed, 0xab, 0x9f, 0x5b, 0x6b, 0x17, 0x65, 0xfa, 0x77, 0xe7, 0xaf, 0xbf, 0x06,
|
||||
0x00, 0x00, 0xff, 0xff, 0x51, 0x2f, 0x5d, 0x6f, 0xed, 0x11, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Row) Marshal() (dAtA []byte, err error) {
|
||||
|
|
@ -3834,15 +3826,12 @@ func (m *Decimal) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
i -= len(m.XXX_unrecognized)
|
||||
copy(dAtA[i:], m.XXX_unrecognized)
|
||||
}
|
||||
if m.Scale != 0 {
|
||||
i = encodeVarintPublic(dAtA, i, uint64(m.Scale))
|
||||
if len(m.Gob) > 0 {
|
||||
i -= len(m.Gob)
|
||||
copy(dAtA[i:], m.Gob)
|
||||
i = encodeVarintPublic(dAtA, i, uint64(len(m.Gob)))
|
||||
i--
|
||||
dAtA[i] = 0x10
|
||||
}
|
||||
if m.Value != 0 {
|
||||
i = encodeVarintPublic(dAtA, i, uint64(m.Value))
|
||||
i--
|
||||
dAtA[i] = 0x8
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
|
@ -5635,11 +5624,9 @@ func (m *Decimal) Size() (n int) {
|
|||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.Value != 0 {
|
||||
n += 1 + sovPublic(uint64(m.Value))
|
||||
}
|
||||
if m.Scale != 0 {
|
||||
n += 1 + sovPublic(uint64(m.Scale))
|
||||
l = len(m.Gob)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovPublic(uint64(l))
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
|
|
@ -8774,10 +8761,10 @@ func (m *Decimal) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Gob", wireType)
|
||||
}
|
||||
m.Value = 0
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowPublic
|
||||
|
|
@ -8787,30 +8774,26 @@ func (m *Decimal) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Value |= int64(b&0x7F) << shift
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Scale", wireType)
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthPublic
|
||||
}
|
||||
m.Scale = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowPublic
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Scale |= int64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthPublic
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Gob = append(m.Gob[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Gob == nil {
|
||||
m.Gob = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipPublic(dAtA[iNdEx:])
|
||||
|
|
|
|||
|
|
@ -113,8 +113,7 @@ message ValCount {
|
|||
}
|
||||
|
||||
message Decimal {
|
||||
int64 Value = 1;
|
||||
int64 Scale = 2;
|
||||
bytes Gob = 1;
|
||||
}
|
||||
|
||||
message DistinctTimestamp {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func TestCondition_StringWithSubj(t *testing.T) {
|
|||
}{
|
||||
{pql.BETWEEN, []interface{}{int64(4), int64(8)}, "4<=subj<=8"},
|
||||
{pql.BETWEEN, []interface{}{uint64(5), uint64(9)}, "5<=subj<=9"},
|
||||
{pql.BETWEEN, []interface{}{pql.Decimal{Value: -401, Scale: 2}, pql.Decimal{Value: 802, Scale: 1}}, "-4.01<=subj<=80.2"},
|
||||
{pql.BETWEEN, []interface{}{pql.NewDecimal(-401, 2), pql.NewDecimal(802, 1)}, "-4.01<=subj<=80.2"},
|
||||
{pql.EQ, nil, "subj==null"},
|
||||
{pql.NEQ, nil, "subj!=null"},
|
||||
} {
|
||||
|
|
|
|||
243
pql/decimal.go
243
pql/decimal.go
|
|
@ -2,7 +2,7 @@
|
|||
package pql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
|
@ -52,22 +52,74 @@ func Pow10(p int64) int64 {
|
|||
// Precision is currently not considered; precision, for
|
||||
// our purposes is implied to be the complete, known value.
|
||||
type Decimal struct {
|
||||
Value int64
|
||||
value big.Int
|
||||
Scale int64
|
||||
}
|
||||
|
||||
func (d *Decimal) Value() big.Int {
|
||||
val := big.NewInt(0)
|
||||
val.Set(&d.value)
|
||||
return *val
|
||||
}
|
||||
|
||||
func (d *Decimal) SetValue(v int64) {
|
||||
val := big.NewInt(v)
|
||||
d.value = *val
|
||||
}
|
||||
|
||||
func (d Decimal) Clone() (r *Decimal) {
|
||||
val := big.NewInt(0)
|
||||
val.Set(&d.value)
|
||||
r = &Decimal{
|
||||
Value: d.Value,
|
||||
value: *val,
|
||||
Scale: d.Scale,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Decimal) GobEncode() ([]byte, error) {
|
||||
if d == nil {
|
||||
return nil, nil
|
||||
}
|
||||
valBuf, err := d.value.GobEncode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valSz := len(valBuf)
|
||||
|
||||
// make a buffer the size of our Decimal, plus our 8 byte Scale,
|
||||
// plus 1 byte for sign of scale
|
||||
buf := make([]byte, valSz+8)
|
||||
copy(buf[:valSz], valBuf)
|
||||
|
||||
binary.LittleEndian.PutUint64(buf[valSz:valSz+8], uint64(d.Scale))
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (d *Decimal) GobDecode(buf []byte) error {
|
||||
if len(buf) == 0 {
|
||||
// they sent a nil or default value
|
||||
*d = Decimal{}
|
||||
return nil
|
||||
}
|
||||
|
||||
valPart := len(buf) - 8
|
||||
value := big.NewInt(0)
|
||||
if err := value.GobDecode(buf[:valPart]); err != nil {
|
||||
return err
|
||||
}
|
||||
d.value = *value
|
||||
|
||||
d.Scale = int64(binary.LittleEndian.Uint64(buf[valPart : valPart+8]))
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewDecimal returns a Decimal based on the provided arguments.
|
||||
func NewDecimal(value, scale int64) Decimal {
|
||||
v := big.NewInt(value)
|
||||
return Decimal{
|
||||
Value: value,
|
||||
value: *v,
|
||||
Scale: scale,
|
||||
}
|
||||
}
|
||||
|
|
@ -84,34 +136,14 @@ func MinMax(scale int64) (Decimal, Decimal) {
|
|||
//
|
||||
// If the Scale of a and b don't match, the returned Decimal will have the
|
||||
// smallest Scale needed to precisely represent the sum.
|
||||
func AddDecimal(a, b Decimal) (Decimal, bool) {
|
||||
av, bv := big.NewInt(a.Value), big.NewInt(b.Value)
|
||||
|
||||
// if the scales dont match,
|
||||
// we add zeros to the end of the one with the smaller scale until they match
|
||||
// or we overflow
|
||||
// then we add the values and return the decimal
|
||||
as, bs := a.Scale, b.Scale
|
||||
var ok bool
|
||||
if a.Scale > b.Scale {
|
||||
av, bv = bv, av
|
||||
as, bs = bs, as
|
||||
}
|
||||
|
||||
for as < bs {
|
||||
av = av.Mul(av, big.NewInt(10))
|
||||
as++
|
||||
}
|
||||
|
||||
av = av.Add(av, bv)
|
||||
ret, ok := av.Int64(), av.IsInt64()
|
||||
if !ok {
|
||||
return Decimal{}, ok
|
||||
}
|
||||
func AddDecimal(a, b Decimal) Decimal {
|
||||
ac, bc := sameScalify(a, b)
|
||||
apv, bpv := &ac.value, &bc.value
|
||||
apv.Add(apv, bpv)
|
||||
return Decimal{
|
||||
Value: ret,
|
||||
Scale: as,
|
||||
}, ok
|
||||
value: *apv,
|
||||
Scale: ac.Scale,
|
||||
}
|
||||
}
|
||||
|
||||
// LessThan returns true if d < d2.
|
||||
|
|
@ -134,84 +166,56 @@ func (d Decimal) GreaterThanOrEqualTo(d2 Decimal) bool {
|
|||
return d.greaterThan(d2, true)
|
||||
}
|
||||
|
||||
// EqualTo returns true if d == d2.
|
||||
func (d Decimal) EqualTo(d2 Decimal) bool {
|
||||
if d.Scale == d2.Scale {
|
||||
return d.Value == d2.Value
|
||||
func (d *Decimal) withLargerScale(scale int64) *Decimal {
|
||||
dc := d.Clone()
|
||||
val := &dc.value
|
||||
ten := big.NewInt(10)
|
||||
for dc.Scale < scale {
|
||||
val = val.Mul(val, ten)
|
||||
dc.Scale++
|
||||
}
|
||||
|
||||
quotientD := quotient(d)
|
||||
quotientD2 := quotient(d2)
|
||||
if quotientD != quotientD2 {
|
||||
return false
|
||||
return dc
|
||||
}
|
||||
|
||||
func sameScalify(d, d2 Decimal) (*Decimal, *Decimal) {
|
||||
dc := d.Clone()
|
||||
d2c := d2.Clone()
|
||||
|
||||
if dc.Scale < d2c.Scale {
|
||||
dc = dc.withLargerScale(d2c.Scale)
|
||||
} else {
|
||||
d2c = d2c.withLargerScale(dc.Scale)
|
||||
}
|
||||
remainderD, remainderD2 := remainder(d), remainder(d2)
|
||||
if d.Scale < d2.Scale {
|
||||
scaleDiff := d2.Scale - d.Scale
|
||||
return (remainderD * pow10[scaleDiff]) == remainderD2
|
||||
|
||||
return dc, d2c
|
||||
}
|
||||
|
||||
func (d Decimal) cmp(d2 Decimal) int {
|
||||
if d.Scale == d2.Scale {
|
||||
return (&d.value).Cmp(&d2.value)
|
||||
}
|
||||
scaleDiff := d.Scale - d2.Scale
|
||||
return remainderD == (remainderD2 * pow10[scaleDiff])
|
||||
dc, d2c := sameScalify(d, d2)
|
||||
return (&dc.value).Cmp(&d2c.value)
|
||||
}
|
||||
|
||||
// EqualTo returns true if d == d2.
|
||||
func (d Decimal) EqualTo(d2 Decimal) bool {
|
||||
return d.cmp(d2) == 0
|
||||
}
|
||||
|
||||
func (d Decimal) lessThan(d2 Decimal, eq bool) bool {
|
||||
if d.Scale == d2.Scale {
|
||||
if eq {
|
||||
return d.Value <= d2.Value
|
||||
}
|
||||
return d.Value < d2.Value
|
||||
if eq {
|
||||
return d.cmp(d2) <= 0
|
||||
}
|
||||
|
||||
quotientD, quotientD2 := quotient(d), quotient(d2)
|
||||
if quotientD < quotientD2 {
|
||||
return true
|
||||
} else if quotientD == quotientD2 {
|
||||
remainderD, remainderD2 := remainder(d), remainder(d2)
|
||||
if d.Scale < d2.Scale {
|
||||
scaleDiff := d2.Scale - d.Scale
|
||||
if eq {
|
||||
return (remainderD * pow10[scaleDiff]) <= remainderD2
|
||||
}
|
||||
return (remainderD * pow10[scaleDiff]) < remainderD2
|
||||
}
|
||||
scaleDiff := d.Scale - d2.Scale
|
||||
if eq {
|
||||
return remainderD <= (remainderD2 * pow10[scaleDiff])
|
||||
}
|
||||
return remainderD < (remainderD2 * pow10[scaleDiff])
|
||||
}
|
||||
|
||||
return false
|
||||
return d.cmp(d2) < 0
|
||||
}
|
||||
|
||||
func (d Decimal) greaterThan(d2 Decimal, eq bool) bool {
|
||||
if d.Scale == d2.Scale {
|
||||
if eq {
|
||||
return d.Value >= d2.Value
|
||||
}
|
||||
return d.Value > d2.Value
|
||||
if eq {
|
||||
return d.cmp(d2) >= 0
|
||||
}
|
||||
|
||||
quotientD, quotientD2 := quotient(d), quotient(d2)
|
||||
if quotientD > quotientD2 {
|
||||
return true
|
||||
} else if quotientD == quotientD2 {
|
||||
remainderD, remainderD2 := remainder(d), remainder(d2)
|
||||
if d.Scale < d2.Scale {
|
||||
scaleDiff := d2.Scale - d.Scale
|
||||
if eq {
|
||||
return (remainderD * pow10[scaleDiff]) >= remainderD2
|
||||
}
|
||||
return (remainderD * pow10[scaleDiff]) > remainderD2
|
||||
}
|
||||
scaleDiff := d.Scale - d2.Scale
|
||||
if eq {
|
||||
return remainderD >= (remainderD2 * pow10[scaleDiff])
|
||||
}
|
||||
return remainderD > (remainderD2 * pow10[scaleDiff])
|
||||
}
|
||||
|
||||
return false
|
||||
return d.cmp(d2) > 0
|
||||
}
|
||||
|
||||
// SupportedByScale returns true if d can be represented
|
||||
|
|
@ -240,16 +244,17 @@ func (d Decimal) IsValid() bool {
|
|||
}
|
||||
|
||||
// ToInt64 returns d as an int64 adjusted to the
|
||||
// provided scale.
|
||||
// provided scale. If d.value cannot be represented
|
||||
// as an int64, results are undefined.
|
||||
func (d Decimal) ToInt64(scale int64) int64 {
|
||||
var ret int64
|
||||
scaleDiff := scale - d.Scale
|
||||
if scaleDiff == 0 {
|
||||
ret = d.Value
|
||||
ret = d.value.Int64()
|
||||
} else if scaleDiff < 0 {
|
||||
ret = d.Value / Pow10(-1*scaleDiff)
|
||||
ret = d.value.Int64() / Pow10(-1*scaleDiff)
|
||||
} else {
|
||||
ret = d.Value * Pow10(scaleDiff)
|
||||
ret = d.value.Int64() * Pow10(scaleDiff)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
@ -257,12 +262,14 @@ func (d Decimal) ToInt64(scale int64) int64 {
|
|||
// Float64 returns d as a float64.
|
||||
// TODO: this could potentially lose precision; we should audit
|
||||
// its use and protect against unexpected results.
|
||||
// If d.value cannot be represented as an int64,
|
||||
// results are undefined.
|
||||
func (d Decimal) Float64() float64 {
|
||||
var ret float64
|
||||
if d.Scale == 0 {
|
||||
ret = float64(d.Value)
|
||||
ret = float64(d.value.Int64())
|
||||
} else {
|
||||
ret = float64(d.Value) / math.Pow10(int(d.Scale))
|
||||
ret = float64(d.value.Int64()) / math.Pow10(int(d.Scale))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
@ -272,7 +279,10 @@ func (d Decimal) String() string {
|
|||
var s string
|
||||
|
||||
var neg bool
|
||||
sval := fmt.Sprintf("%d", d.Value)
|
||||
sval := d.value.String()
|
||||
if len(sval) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Strip the negative sign off for now, and
|
||||
// re-apply it at the end.
|
||||
|
|
@ -441,8 +451,9 @@ func ParseDecimal(s string) (Decimal, error) {
|
|||
value *= -1
|
||||
}
|
||||
|
||||
bigVal := big.NewInt(value)
|
||||
return Decimal{
|
||||
Value: value,
|
||||
value: *bigVal,
|
||||
Scale: scale,
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -489,24 +500,6 @@ func reducePrecision(sign bool, mantissa []byte, scale int64) ([]byte, int64, bo
|
|||
return reducePrecision(sign, mantissa[:len(mantissa)-1], scale-1)
|
||||
}
|
||||
|
||||
func quotient(d Decimal) int64 {
|
||||
if d.Scale == 0 {
|
||||
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
|
||||
}
|
||||
|
||||
func remainder(d Decimal) int64 {
|
||||
if d.Scale >= 0 && d.Scale < 19 {
|
||||
return d.Value % pow10[d.Scale]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a custom unmarshaller for the Decimal
|
||||
// type. The intention is to avoid the use of float64
|
||||
// anywhere, so this unmarhaller parses the decimal out
|
||||
|
|
@ -516,7 +509,7 @@ func (d *Decimal) UnmarshalJSON(data []byte) error {
|
|||
if err != nil {
|
||||
return errors.Wrapf(err, "parsing decimal: %s", string(data))
|
||||
}
|
||||
d.Value = o.Value
|
||||
d.value = o.value
|
||||
d.Scale = o.Scale
|
||||
|
||||
return nil
|
||||
|
|
@ -539,7 +532,7 @@ func (d *Decimal) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if err != nil {
|
||||
return errors.Wrapf(err, "parsing decimal: %s", data)
|
||||
}
|
||||
d.Value = o.Value
|
||||
d.value = o.value
|
||||
d.Scale = o.Scale
|
||||
|
||||
return nil
|
||||
|
|
|
|||
133
pql/decimal_internal_test.go
Normal file
133
pql/decimal_internal_test.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package pql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testAddDecimalCase struct {
|
||||
a Decimal
|
||||
b Decimal
|
||||
exp Decimal
|
||||
}
|
||||
|
||||
func TestAddDecimal(t *testing.T) {
|
||||
toDecimal := func(a interface{}) Decimal {
|
||||
switch ac := a.(type) {
|
||||
case string:
|
||||
return mustParse(t, ac)
|
||||
case Decimal:
|
||||
return ac
|
||||
default:
|
||||
t.Fatalf("cannot support type %T", ac)
|
||||
}
|
||||
return Decimal{}
|
||||
}
|
||||
|
||||
newTestAddDecimalCase := func(a, b, exp interface{}) testAddDecimalCase {
|
||||
return testAddDecimalCase{
|
||||
a: toDecimal(a),
|
||||
b: toDecimal(b),
|
||||
exp: toDecimal(exp),
|
||||
}
|
||||
}
|
||||
|
||||
tests := []testAddDecimalCase{
|
||||
newTestAddDecimalCase("40.37", "40.37", "80.74"),
|
||||
newTestAddDecimalCase("18.5", "9.25", "27.75"),
|
||||
newTestAddDecimalCase("18.50", "9.25", "27.75"),
|
||||
newTestAddDecimalCase("-18.50", "-9.25", "-27.75"),
|
||||
newTestAddDecimalCase("-40.37", "40.37", NewDecimal(0, 0)),
|
||||
newTestAddDecimalCase("-50.38", "-50.38", "-100.76"),
|
||||
newTestAddDecimalCase("-40.381", "-40.38", "-80.761"),
|
||||
newTestAddDecimalCase("-40.3700000000000000000001", "-50.38", "-90.7500000000000000000001"),
|
||||
newTestAddDecimalCase("10.37000000000000001", "-10", "0.37000000000000001"),
|
||||
// this is a weird one. because we reduce precision when we parse strings, we
|
||||
// expect the value to be smaller than it really should be if you did
|
||||
// the math yourself.
|
||||
//
|
||||
// there's not really a good way around this unless we use math/big.Int to represent
|
||||
// our Value/Scale.
|
||||
//
|
||||
// but if we did this, to quote seebs: "i suspect that
|
||||
// our performance would tank so badly by the time we were doing >63-bit
|
||||
// numbers that there's no real-world benefit to us."
|
||||
newTestAddDecimalCase("10.370000000000000001", "-10", "0.37"),
|
||||
newTestAddDecimalCase("-9223372036854775807", "-9223372036854775807", "-18446744073709551614"),
|
||||
newTestAddDecimalCase("9223372036854775807", "9223372036854775807", "18446744073709551614"),
|
||||
newTestAddDecimalCase(NewDecimal(0, 0), NewDecimal(1, 4), NewDecimal(1, 4)),
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
t.Logf("first %#v %#v", test.a, test.b)
|
||||
if got := AddDecimal(test.a, test.b); !got.EqualTo(test.exp) {
|
||||
t.Logf("LOG: %#v + %#v, expected %#v, got %#v", test.a, test.b, test.exp, got)
|
||||
t.Errorf("%v + %v, expected %v, got %v", test.a, test.b, test.exp, got)
|
||||
}
|
||||
|
||||
t.Logf("second %v %v", test.a, test.b)
|
||||
if got := AddDecimal(test.b, test.a); !got.EqualTo(test.exp) {
|
||||
t.Logf("LOG: %#v + %#v, expected %#v, got %#v", test.a, test.b, test.exp, got)
|
||||
t.Errorf("%v + %v, expected %v, got %v", test.b, test.a, test.exp, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustParse(t *testing.T, num string) Decimal {
|
||||
t.Helper()
|
||||
d, err := ParseDecimal(num)
|
||||
if err != nil {
|
||||
v := big.NewInt(0)
|
||||
if _, ok := v.SetString(num, 10); !ok {
|
||||
t.Fatalf("unexpected error parsing %s to Decimal: %v", num, err)
|
||||
}
|
||||
d.value = *v
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func TestGobEncodeDecode(t *testing.T) {
|
||||
for i := int64(-10); i < 10; i++ {
|
||||
for j := int64(-10); j < 10; j++ {
|
||||
decimal := &Decimal{value: *(big.NewInt(i)), Scale: j}
|
||||
t.Run(fmt.Sprintf("v%ds%d", i, j), func(t *testing.T) {
|
||||
encoded, err := decimal.GobEncode()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
decoded := &Decimal{}
|
||||
err = decoded.GobDecode(encoded)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(decimal, decoded) {
|
||||
t.Errorf("%v != %v", decimal, encoded)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
i := int64(math.MaxInt64)
|
||||
j := int64(math.MinInt64)
|
||||
decimal := &Decimal{value: *(big.NewInt(i)), Scale: j}
|
||||
t.Run(fmt.Sprintf("v%ds%d", i, j), func(t *testing.T) {
|
||||
encoded, err := decimal.GobEncode()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
decoded := &Decimal{}
|
||||
err = decoded.GobDecode(encoded)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(decimal, decoded) {
|
||||
t.Errorf("%v != %v", decimal, encoded)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package pql_test
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
|
@ -19,48 +18,48 @@ func TestDecimal(t *testing.T) {
|
|||
exp pql.Decimal
|
||||
expErr string
|
||||
}{
|
||||
{"0", pql.Decimal{0, 0}, ""},
|
||||
{"-0", pql.Decimal{0, 0}, ""},
|
||||
{"0.0", pql.Decimal{0, 0}, ""},
|
||||
{"0.", pql.Decimal{0, 0}, ""},
|
||||
{"-0.00", pql.Decimal{0, 0}, ""},
|
||||
{"123.4567", pql.Decimal{1234567, 4}, ""},
|
||||
{"123.456700", pql.Decimal{1234567, 4}, ""},
|
||||
{"00123.4567", pql.Decimal{1234567, 4}, ""},
|
||||
{"+123.4567", pql.Decimal{1234567, 4}, ""},
|
||||
{"-123.4567", pql.Decimal{-1234567, 4}, ""},
|
||||
{"-00123.4567", pql.Decimal{-1234567, 4}, ""},
|
||||
{"-12.25", pql.Decimal{-1225, 2}, ""},
|
||||
{"0", pql.NewDecimal(0, 0), ""},
|
||||
{"-0", pql.NewDecimal(0, 0), ""},
|
||||
{"0.0", pql.NewDecimal(0, 0), ""},
|
||||
{"0.", pql.NewDecimal(0, 0), ""},
|
||||
{"-0.00", pql.NewDecimal(0, 0), ""},
|
||||
{"123.4567", pql.NewDecimal(1234567, 4), ""},
|
||||
{"123.456700", pql.NewDecimal(1234567, 4), ""},
|
||||
{"00123.4567", pql.NewDecimal(1234567, 4), ""},
|
||||
{"+123.4567", pql.NewDecimal(1234567, 4), ""},
|
||||
{"-123.4567", pql.NewDecimal(-1234567, 4), ""},
|
||||
{"-00123.4567", pql.NewDecimal(-1234567, 4), ""},
|
||||
{"-12.25", pql.NewDecimal(-1225, 2), ""},
|
||||
|
||||
{"123", pql.Decimal{123, 0}, ""},
|
||||
{"-12300", pql.Decimal{-123, -2}, ""},
|
||||
{"+012300", pql.Decimal{123, -2}, ""},
|
||||
{"12300", pql.Decimal{123, -2}, ""},
|
||||
{"12300.", pql.Decimal{123, -2}, ""},
|
||||
{"12300.0", pql.Decimal{123, -2}, ""},
|
||||
{"123.0", pql.Decimal{123, 0}, ""},
|
||||
{"123", pql.NewDecimal(123, 0), ""},
|
||||
{"-12300", pql.NewDecimal(-123, -2), ""},
|
||||
{"+012300", pql.NewDecimal(123, -2), ""},
|
||||
{"12300", pql.NewDecimal(123, -2), ""},
|
||||
{"12300.", pql.NewDecimal(123, -2), ""},
|
||||
{"12300.0", pql.NewDecimal(123, -2), ""},
|
||||
{"123.0", pql.NewDecimal(123, 0), ""},
|
||||
|
||||
{".123", pql.Decimal{123, 3}, ""},
|
||||
{"0.123", pql.Decimal{123, 3}, ""},
|
||||
{"0.001230", pql.Decimal{123, 5}, ""},
|
||||
{"-0.001230", pql.Decimal{-123, 5}, ""},
|
||||
{".123", pql.NewDecimal(123, 3), ""},
|
||||
{"0.123", pql.NewDecimal(123, 3), ""},
|
||||
{"0.001230", pql.NewDecimal(123, 5), ""},
|
||||
{"-0.001230", pql.NewDecimal(-123, 5), ""},
|
||||
|
||||
// int64 edges.
|
||||
{".000009223372036854775807", pql.Decimal{9223372036854775807, 24}, ""},
|
||||
{"-.000009223372036854775808", pql.Decimal{-9223372036854775808, 24}, ""},
|
||||
{"92233720368547.75807", pql.Decimal{9223372036854775807, 5}, ""},
|
||||
{"-92233720368547.75807", pql.Decimal{-9223372036854775807, 5}, ""},
|
||||
{"9223372036854775807000", pql.Decimal{9223372036854775807, -3}, ""},
|
||||
{"-9223372036854775807000", pql.Decimal{-9223372036854775807, -3}, ""},
|
||||
{".000009223372036854775807", pql.NewDecimal(9223372036854775807, 24), ""},
|
||||
{"-.000009223372036854775808", pql.NewDecimal(-9223372036854775808, 24), ""},
|
||||
{"92233720368547.75807", pql.NewDecimal(9223372036854775807, 5), ""},
|
||||
{"-92233720368547.75807", pql.NewDecimal(-9223372036854775807, 5), ""},
|
||||
{"9223372036854775807000", pql.NewDecimal(9223372036854775807, -3), ""},
|
||||
{"-9223372036854775807000", pql.NewDecimal(-9223372036854775807, -3), ""},
|
||||
|
||||
// precision adjustment
|
||||
{"2.666666666666666667", pql.Decimal{2666666666666666667, 18}, ""},
|
||||
{"2.6666666666666666667", pql.Decimal{2666666666666666666, 18}, ""},
|
||||
{"2.6666666666666666666667", pql.Decimal{2666666666666666666, 18}, ""},
|
||||
{"-9.223372036854775808", pql.Decimal{-9223372036854775808, 18}, ""},
|
||||
{"-9.223372036854775809", pql.Decimal{-922337203685477580, 17}, ""},
|
||||
{"9.223372036854775807", pql.Decimal{9223372036854775807, 18}, ""},
|
||||
{"9.223372036854775808", pql.Decimal{922337203685477580, 17}, ""},
|
||||
{"2.666666666666666667", pql.NewDecimal(2666666666666666667, 18), ""},
|
||||
{"2.6666666666666666667", pql.NewDecimal(2666666666666666666, 18), ""},
|
||||
{"2.6666666666666666666667", pql.NewDecimal(2666666666666666666, 18), ""},
|
||||
{"-9.223372036854775808", pql.NewDecimal(-9223372036854775808, 18), ""},
|
||||
{"-9.223372036854775809", pql.NewDecimal(-922337203685477580, 17), ""},
|
||||
{"9.223372036854775807", pql.NewDecimal(9223372036854775807, 18), ""},
|
||||
{"9.223372036854775808", pql.NewDecimal(922337203685477580, 17), ""},
|
||||
|
||||
// Error cases.
|
||||
{"", pql.Decimal{}, "decimal string is empty"},
|
||||
|
|
@ -88,7 +87,7 @@ func TestDecimal(t *testing.T) {
|
|||
}
|
||||
} else if err != nil {
|
||||
t.Fatalf("test %d parsing string `%s`: %s", i, test.s, err)
|
||||
} else if dec != test.exp {
|
||||
} else if !dec.EqualTo(test.exp) {
|
||||
t.Fatalf("test %d parsing string `%s`: expected: %v, but got: %v", i, test.s, test.exp, dec)
|
||||
}
|
||||
}
|
||||
|
|
@ -100,22 +99,22 @@ func TestDecimal(t *testing.T) {
|
|||
scale int64
|
||||
exp int64
|
||||
}{
|
||||
{pql.Decimal{0, 0}, 0, 0}, // 0 : 0
|
||||
{pql.Decimal{0, 0}, 1, 0}, // 0 : 0.0
|
||||
{pql.Decimal{0, 0}, -1, 0}, // 0 : 0
|
||||
{pql.NewDecimal(0, 0), 0, 0}, // 0 : 0
|
||||
{pql.NewDecimal(0, 0), 1, 0}, // 0 : 0.0
|
||||
{pql.NewDecimal(0, 0), -1, 0}, // 0 : 0
|
||||
|
||||
{pql.Decimal{1234567, 4}, 5, 12345670}, // 123.4567 : 123.45670
|
||||
{pql.Decimal{1234567, 4}, 4, 1234567}, // 123.4567 : 123.4567
|
||||
{pql.Decimal{1234567, 4}, 3, 123456}, // 123.4567 : 123.456
|
||||
{pql.NewDecimal(1234567, 4), 5, 12345670}, // 123.4567 : 123.45670
|
||||
{pql.NewDecimal(1234567, 4), 4, 1234567}, // 123.4567 : 123.4567
|
||||
{pql.NewDecimal(1234567, 4), 3, 123456}, // 123.4567 : 123.456
|
||||
|
||||
{pql.Decimal{-1234567, 4}, 5, -12345670}, // -123.4567 : -123.45670
|
||||
{pql.Decimal{-1234567, 4}, 4, -1234567}, // -123.4567 : -123.4567
|
||||
{pql.Decimal{-1234567, 4}, 3, -123456}, // -123.4567 : -123.456
|
||||
{pql.NewDecimal(-1234567, 4), 5, -12345670}, // -123.4567 : -123.45670
|
||||
{pql.NewDecimal(-1234567, 4), 4, -1234567}, // -123.4567 : -123.4567
|
||||
{pql.NewDecimal(-1234567, 4), 3, -123456}, // -123.4567 : -123.456
|
||||
|
||||
{pql.Decimal{123, -2}, 5, 1230000000}, // 12300 : 12300.00000
|
||||
{pql.Decimal{123, -2}, -1, 1230}, // 12300 : 1230
|
||||
{pql.Decimal{123, 1}, -1, 1}, // 12.3 : 1
|
||||
{pql.Decimal{123, 1}, -2, 0}, // 12.3 : 0
|
||||
{pql.NewDecimal(123, -2), 5, 1230000000}, // 12300 : 12300.00000
|
||||
{pql.NewDecimal(123, -2), -1, 1230}, // 12300 : 1230
|
||||
{pql.NewDecimal(123, 1), -1, 1}, // 12.3 : 1
|
||||
{pql.NewDecimal(123, 1), -2, 0}, // 12.3 : 0
|
||||
}
|
||||
for i, test := range tests {
|
||||
v := test.dec.ToInt64(test.scale)
|
||||
|
|
@ -248,86 +247,3 @@ func TestDecimal(t *testing.T) {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
type testAddDecimalCase struct {
|
||||
a pql.Decimal
|
||||
b pql.Decimal
|
||||
exp pql.Decimal
|
||||
notOk bool
|
||||
}
|
||||
|
||||
func TestAddDecimal(t *testing.T) {
|
||||
toDecimal := func(a interface{}) pql.Decimal {
|
||||
switch ac := a.(type) {
|
||||
case string:
|
||||
return mustParse(t, ac)
|
||||
case pql.Decimal:
|
||||
return ac
|
||||
default:
|
||||
t.Fatalf("cannot support type %T", ac)
|
||||
}
|
||||
return pql.Decimal{}
|
||||
}
|
||||
|
||||
newTestAddDecimalCase := func(a, b, exp interface{}, notOk bool) testAddDecimalCase {
|
||||
return testAddDecimalCase{
|
||||
a: toDecimal(a),
|
||||
b: toDecimal(b),
|
||||
exp: toDecimal(exp),
|
||||
notOk: notOk,
|
||||
}
|
||||
}
|
||||
|
||||
tests := []testAddDecimalCase{
|
||||
newTestAddDecimalCase("40.37", "40.37", "80.74", false),
|
||||
newTestAddDecimalCase("18.5", "9.25", "27.75", false),
|
||||
newTestAddDecimalCase("18.50", "9.25", "27.75", false),
|
||||
newTestAddDecimalCase("-18.50", "-9.25", "-27.75", false),
|
||||
newTestAddDecimalCase("-40.37", "40.37", "0", false),
|
||||
newTestAddDecimalCase("-50.38", "-50.38", "-100.76", false),
|
||||
newTestAddDecimalCase("-40.381", "-40.38", "-80.761", false),
|
||||
newTestAddDecimalCase("-40.3700000000000000000001", "-50.38", "-90.7500000000000000000001", false),
|
||||
newTestAddDecimalCase("10.37000000000000001", "-10", "0.37000000000000001", false),
|
||||
// this is a weird one. because we reduce precision when we parse strings, we
|
||||
// expect the value to be smaller than it really should be if you did
|
||||
// the math yourself.
|
||||
//
|
||||
// there's not really a good way around this unless we use math/big.Int to represent
|
||||
// our Value/Scale.
|
||||
//
|
||||
// but if we did this, to quote seebs: "i suspect that
|
||||
// our performance would tank so badly by the time we were doing >63-bit
|
||||
// numbers that there's no real-world benefit to us."
|
||||
newTestAddDecimalCase("10.370000000000000001", "-10", "0.37", false),
|
||||
newTestAddDecimalCase("-9223372036854775807", "-9223372036854775807", pql.Decimal{}, true),
|
||||
newTestAddDecimalCase("9223372036854775807", "9223372036854775807", pql.Decimal{}, true),
|
||||
newTestAddDecimalCase(pql.Decimal{Value: 0, Scale: 0}, pql.Decimal{Value: 1, Scale: 4}, pql.Decimal{Value: 1, Scale: 4}, false),
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
if got, ok := pql.AddDecimal(test.a, test.b); !got.EqualTo(test.exp) {
|
||||
t.Logf("%#v + %#v, expected %#v, got %#v", test.a, test.b, test.exp, got)
|
||||
t.Errorf("%v + %v, expected %v, got %v", test.a, test.b, test.exp, got)
|
||||
} else if !ok != test.notOk {
|
||||
t.Errorf("expected %v, got %v", test.notOk, ok)
|
||||
}
|
||||
|
||||
if got, ok := pql.AddDecimal(test.b, test.a); !got.EqualTo(test.exp) {
|
||||
t.Logf("%#v + %#v, expected %#v, got %#v", test.a, test.b, test.exp, got)
|
||||
t.Errorf("%v + %v, expected %v, got %v", test.b, test.a, test.exp, got)
|
||||
} else if !ok != test.notOk {
|
||||
t.Errorf("expected %v, got %v", test.notOk, ok)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustParse(t *testing.T, num string) pql.Decimal {
|
||||
t.Helper()
|
||||
d, err := pql.ParseDecimal(num)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error parsing %s to pql.Decimal: %v", num, err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ func TestParser_Parse(t *testing.T) {
|
|||
&pql.Call{
|
||||
Name: "Row",
|
||||
Args: map[string]interface{}{
|
||||
"key": pql.Decimal{1225, 2},
|
||||
"foo": pql.Decimal{13167, 3},
|
||||
"bar": pql.Decimal{2, 0},
|
||||
"baz": pql.Decimal{9, 1},
|
||||
"key": pql.NewDecimal(1225, 2),
|
||||
"foo": pql.NewDecimal(13167, 3),
|
||||
"bar": pql.NewDecimal(2, 0),
|
||||
"baz": pql.NewDecimal(9, 1),
|
||||
},
|
||||
},
|
||||
) {
|
||||
|
|
@ -114,7 +114,7 @@ func TestParser_Parse(t *testing.T) {
|
|||
&pql.Call{
|
||||
Name: "Row",
|
||||
Args: map[string]interface{}{
|
||||
"key": pql.Decimal{-1225, 2},
|
||||
"key": pql.NewDecimal(-1225, 2),
|
||||
"foo": int64(-13),
|
||||
},
|
||||
},
|
||||
|
|
@ -170,7 +170,7 @@ func TestParser_Parse(t *testing.T) {
|
|||
Name: "Row",
|
||||
Args: map[string]interface{}{
|
||||
"key": "foo",
|
||||
"x": &pql.Condition{Op: pql.EQ, Value: pql.Decimal{1225, 2}},
|
||||
"x": &pql.Condition{Op: pql.EQ, Value: pql.NewDecimal(1225, 2)},
|
||||
"y": &pql.Condition{Op: pql.GTE, Value: int64(100)},
|
||||
"z": &pql.Condition{Op: pql.BETWEEN, Value: []interface{}{int64(4), int64(8)}},
|
||||
"m": &pql.Condition{Op: pql.NEQ, Value: nil},
|
||||
|
|
|
|||
|
|
@ -1044,8 +1044,9 @@ func (h *GRPCHandler) Inspect(req *pb.InspectRequest, stream pb.Pilosa_InspectSe
|
|||
if len(resp.Results) > 0 {
|
||||
valCount, ok := resp.Results[0].(pilosa.ValCount)
|
||||
if ok && valCount.Count == 1 {
|
||||
valVal := valCount.DecimalVal.Value()
|
||||
rowResp.Columns = append(rowResp.Columns,
|
||||
&pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_DecimalVal{DecimalVal: &pb.Decimal{Value: valCount.DecimalVal.Value, Scale: valCount.DecimalVal.Scale}}})
|
||||
&pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_DecimalVal{DecimalVal: &pb.Decimal{Value: (&valVal).Int64(), Scale: valCount.DecimalVal.Scale}}})
|
||||
colAdded++
|
||||
} else {
|
||||
rowResp.Columns = append(rowResp.Columns,
|
||||
|
|
@ -1371,8 +1372,9 @@ func (h *GRPCHandler) Inspect(req *pb.InspectRequest, stream pb.Pilosa_InspectSe
|
|||
if len(resp.Results) > 0 {
|
||||
valCount, ok := resp.Results[0].(pilosa.ValCount)
|
||||
if ok && valCount.Count == 1 {
|
||||
valVal := valCount.DecimalVal.Value()
|
||||
rowResp.Columns = append(rowResp.Columns,
|
||||
&pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_DecimalVal{DecimalVal: &pb.Decimal{Value: valCount.DecimalVal.Value, Scale: valCount.DecimalVal.Scale}}})
|
||||
&pb.ColumnResponse{ColumnVal: &pb.ColumnResponse_DecimalVal{DecimalVal: &pb.Decimal{Value: (&valVal).Int64(), Scale: valCount.DecimalVal.Scale}}})
|
||||
colAdded++
|
||||
} else {
|
||||
rowResp.Columns = append(rowResp.Columns,
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
f, err = i2.CreateFieldIfNotExists("f2", pilosa.OptFieldTypeDecimal(1, pql.Decimal{Value: -10}, pql.Decimal{Value: 10}))
|
||||
f, err = i2.CreateFieldIfNotExists("f2", pilosa.OptFieldTypeDecimal(1, pql.NewDecimal(-10, 0), pql.NewDecimal(10, 0)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -744,10 +744,10 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
if field != nil { // happy linter
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MinInt64, 0), field.Options.Min) {
|
||||
t.Fatalf("field min %d != %d", int64(math.MinInt64), field.Options.Min)
|
||||
t.Fatalf("field min %v != %v", int64(math.MinInt64), field.Options.Min)
|
||||
}
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MaxInt64, 0), field.Options.Max) {
|
||||
t.Fatalf("field max %d != %d", int64(math.MaxInt64), field.Options.Max)
|
||||
t.Fatalf("field max %v != %v", int64(math.MaxInt64), field.Options.Max)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -775,10 +775,10 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
if field != nil { // happy linter
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MinInt64, 0), field.Options.Min) {
|
||||
t.Fatalf("field min %d != %d", int64(math.MinInt64), field.Options.Min)
|
||||
t.Fatalf("field min %v != %v", int64(math.MinInt64), field.Options.Min)
|
||||
}
|
||||
if !reflect.DeepEqual(pql.NewDecimal(1, -1), field.Options.Max) {
|
||||
t.Fatalf("field max %d != %d", 10, field.Options.Max)
|
||||
t.Fatalf("field max %v != %v", 10, field.Options.Max)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -806,10 +806,10 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
if field != nil { // happy linter
|
||||
if !reflect.DeepEqual(pql.NewDecimal(-1, -1), field.Options.Min) {
|
||||
t.Fatalf("field min %d != %d", 10, field.Options.Min)
|
||||
t.Fatalf("field min %v != %v", 10, field.Options.Min)
|
||||
}
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MaxInt64, 0), field.Options.Max) {
|
||||
t.Fatalf("field max %d != %d", int64(math.MaxInt64), field.Options.Max)
|
||||
t.Fatalf("field max %v != %v", int64(math.MaxInt64), field.Options.Max)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -847,10 +847,10 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
if field != nil { // happy linter
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MinInt64, 0), field.Options.Min) {
|
||||
t.Fatalf("field min %d != %d", int64(math.MinInt64), field.Options.Min)
|
||||
t.Fatalf("field min %v != %v", int64(math.MinInt64), field.Options.Min)
|
||||
}
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MaxInt64, 0), field.Options.Max) {
|
||||
t.Fatalf("field max %d != %d", int64(math.MaxInt64), field.Options.Max)
|
||||
t.Fatalf("field max %v != %v", int64(math.MaxInt64), field.Options.Max)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -879,10 +879,10 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
if field != nil { // happy linter
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MinInt64, 1), field.Options.Min) {
|
||||
t.Fatalf("field min %d != %d", pql.NewDecimal(math.MinInt64, 1), field.Options.Min)
|
||||
t.Fatalf("field min %v != %v", pql.NewDecimal(math.MinInt64, 1), field.Options.Min)
|
||||
}
|
||||
if !reflect.DeepEqual(pql.NewDecimal(105, 1), field.Options.Max) {
|
||||
t.Fatalf("field max %s != %d", pql.NewDecimal(105, 1), field.Options.Max)
|
||||
t.Fatalf("field max %v != %v", pql.NewDecimal(105, 1), field.Options.Max)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -910,10 +910,10 @@ func TestHandler_Endpoints(t *testing.T) {
|
|||
}
|
||||
if field != nil { // happy linter
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MinInt64, 2), field.Options.Min) {
|
||||
t.Fatalf("field min %d != %d", pql.NewDecimal(math.MinInt64, 1), field.Options.Min)
|
||||
t.Fatalf("field min %v != %v", pql.NewDecimal(math.MinInt64, 1), field.Options.Min)
|
||||
}
|
||||
if !reflect.DeepEqual(pql.NewDecimal(math.MaxInt64, 2), field.Options.Max) {
|
||||
t.Fatalf("field min %d != %d", pql.NewDecimal(math.MaxInt64, 2), field.Options.Max)
|
||||
t.Fatalf("field min %v != %v", pql.NewDecimal(math.MaxInt64, 2), field.Options.Max)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -467,10 +467,10 @@ func pgWriteRowser(w pg.QueryResultWriter, result pb.ToRowser) error {
|
|||
case *pb.ColumnResponse_BoolVal:
|
||||
v = strconv.FormatBool(col.BoolVal)
|
||||
case *pb.ColumnResponse_DecimalVal:
|
||||
v = pql.Decimal{
|
||||
Value: col.DecimalVal.Value,
|
||||
Scale: col.DecimalVal.Scale,
|
||||
}.String()
|
||||
v = pql.NewDecimal(
|
||||
col.DecimalVal.Value,
|
||||
col.DecimalVal.Scale,
|
||||
).String()
|
||||
case *pb.ColumnResponse_Float64Val:
|
||||
v = strconv.FormatFloat(col.Float64Val, 'g', -1, 64)
|
||||
case *pb.ColumnResponse_Int64Val:
|
||||
|
|
|
|||
|
|
@ -197,8 +197,8 @@ func TestMain_MinMaxFloat(t *testing.T) {
|
|||
}
|
||||
|
||||
// Query row.
|
||||
exp0 := pilosa.ValCount{DecimalVal: &pql.Decimal{Value: 4440, Scale: 3}, Count: 1}
|
||||
exp1 := pilosa.ValCount{DecimalVal: &pql.Decimal{Value: 1320, Scale: 3}, Count: 1}
|
||||
exp0 := pilosa.ValCount{DecimalVal: pql.NewDecimal(4440, 3).Clone(), Count: 1}
|
||||
exp1 := pilosa.ValCount{DecimalVal: pql.NewDecimal(1320, 3).Clone(), Count: 1}
|
||||
if res, err := m.QueryProtobuf("i", `Max(field=dec) Min(field=dec)`); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(res.Results[0], exp0) || !reflect.DeepEqual(res.Results[1], exp1) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue