Revert "FB-1491: Revert pql.Decimal commit for the 4.8.5 release (#2117)"

This reverts commit acbcec54c8.
This commit is contained in:
reesporte 2022-06-17 10:21:57 -05:00 committed by reesporte
parent f08d3e2834
commit 0d91e2991d
21 changed files with 626 additions and 420 deletions

View file

@ -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())

View file

@ -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")

View file

@ -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

View file

@ -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,
}
}

View file

@ -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
}
@ -1894,6 +1892,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))
dec := pql.NewDecimal((int64(vsum) + (int64(vcount) * bsig.Base)), bsig.Scale)
out.DecimalVal = &dec
}
return out, nil
}
@ -3117,7 +3117,7 @@ func (e *executor) executeGroupBy(ctx context.Context, qcx *Qcx, index string, c
}
}
for _, res := range results {
if res.DecimalAgg != 0 && aggType == "sum" {
if res.DecimalAgg != nil && aggType == "sum" {
aggType = "decimalSum"
break
}
@ -3361,31 +3361,31 @@ func (g *GroupCounts) MarshalJSON() ([]byte, error) {
// GroupCount represents a result item for a group by query.
type GroupCount struct {
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"-"`
DecimalAgg float64 `json:"-"`
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"-"`
DecimalAgg *pql.Decimal `json:"-"`
}
type groupCountSum struct {
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"sum"`
DecimalAgg float64 `json:"-"`
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"sum"`
DecimalAgg *pql.Decimal `json:"-"`
}
type groupCountAggregate struct {
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"aggregate"`
DecimalAgg float64 `json:"-"`
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"aggregate"`
DecimalAgg *pql.Decimal `json:"-"`
}
type groupCountDecimalSum struct {
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"-"`
DecimalAgg float64 `json:"sum"`
Group []FieldRow `json:"group"`
Count uint64 `json:"count"`
Agg int64 `json:"-"`
DecimalAgg *pql.Decimal `json:"sum"`
}
var _ GroupCount = GroupCount(groupCountSum{})
@ -3422,7 +3422,10 @@ func mergeGroupCounts(a, b []GroupCount, limit int) []GroupCount {
case 0:
a[i].Count += b[j].Count
a[i].Agg += b[j].Agg
a[i].DecimalAgg += b[j].DecimalAgg
if a[i].DecimalAgg != nil && b[j].DecimalAgg != nil {
sum := pql.AddDecimal(*a[i].DecimalAgg, *b[j].DecimalAgg)
a[i].DecimalAgg = &sum
}
ret = append(ret, a[i])
i++
j++
@ -3972,10 +3975,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,
},
},
@ -7772,10 +7777,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")
@ -8244,7 +8251,7 @@ func (gbi *groupByIterator) Next(ctx context.Context) (ret GroupCount, done bool
}
ret.Count = uint64(result.Count)
ret.Agg = result.Val
ret.DecimalAgg = result.FloatVal
ret.DecimalAgg = result.DecimalVal
}
}
if ret.Count == 0 {

View file

@ -2279,31 +2279,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,
@ -2859,7 +2859,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))
}
})
@ -2867,7 +2867,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))
}
})
@ -2875,7 +2875,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))
}
})
@ -2883,7 +2883,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))
}
})
@ -4046,7 +4046,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:
@ -5368,15 +5368,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: 27.75},
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Agg: 3220, DecimalAgg: 32.20},
{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: -277.5},
{Group: []pilosa.FieldRow{{Field: "generals", RowID: 2, RowKey: "r2"}}, Count: 5, Agg: -3220, DecimalAgg: -322.0},
{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()},
},
},
{
@ -5519,7 +5519,7 @@ func TestExecutor_GroupByStrings(t *testing.T) {
}
for i, tst := range tests {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Run(fmt.Sprintf("%s%d", tst.query, i), func(t *testing.T) {
r, err := c.GetNode(0).API.Query(context.Background(), &pilosa.QueryRequest{
Index: "istring",
Query: tst.query,
@ -8673,7 +8673,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
})

View file

@ -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) {

View file

@ -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)

View file

@ -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

View file

@ -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")
}

View file

@ -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:])

View file

@ -113,8 +113,7 @@ message ValCount {
}
message Decimal {
int64 Value = 1;
int64 Scale = 2;
bytes Gob = 1;
}
message DistinctTimestamp {

View file

@ -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"},
} {

View file

@ -2,8 +2,9 @@
package pql
import (
"fmt"
"encoding/binary"
"math"
"math/big"
"strconv"
"strings"
@ -51,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,
}
}
@ -79,6 +132,20 @@ func MinMax(scale int64) (Decimal, Decimal) {
return min, max
}
// AddDecimal adds a and b together and returns a new Decimal with the computed sum.
//
// 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 {
ac, bc := sameScalify(a, b)
apv, bpv := &ac.value, &bc.value
apv.Add(apv, bpv)
return Decimal{
value: *apv,
Scale: ac.Scale,
}
}
// LessThan returns true if d < d2.
func (d Decimal) LessThan(d2 Decimal) bool {
return d.lessThan(d2, false)
@ -99,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
@ -205,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
}
@ -222,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
}
@ -237,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.
@ -388,7 +433,6 @@ func ParseDecimal(s string) (Decimal, error) {
} else {
return Decimal{}, errors.Errorf("value out of range: %s", mantissa)
}
// We have to use ParseUint here (as opposed to ParseInt) because
// math.MinInt64 is a valid value, but its absolute value is not.
// So this allows us to handle that one value without overflow, and
@ -407,8 +451,9 @@ func ParseDecimal(s string) (Decimal, error) {
value *= -1
}
bigVal := big.NewInt(value)
return Decimal{
Value: value,
value: *bigVal,
Scale: scale,
}, nil
}
@ -455,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
@ -482,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
@ -505,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

View 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)
}
})
}

View file

@ -18,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"},
@ -87,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)
}
}
@ -99,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)

View file

@ -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},

View file

@ -1053,8 +1053,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,
@ -1380,8 +1381,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,

View file

@ -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)
}
}
})

View file

@ -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:

View file

@ -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) {