mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 00:55:55 +00:00
resolve conflict
This commit is contained in:
commit
756fc49be6
12 changed files with 205 additions and 93 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
default.etcd/
|
||||
*.test
|
||||
vendor
|
||||
.protoc-gen-gofast
|
||||
|
|
|
|||
13
Makefile
13
Makefile
|
|
@ -1,6 +1,7 @@
|
|||
.PHONY: glide vendor-update docker pilosa pilosactl crossbuild install
|
||||
.PHONY: glide vendor-update docker pilosa pilosactl crossbuild install generate
|
||||
|
||||
GLIDE := $(shell command -v glide 2>/dev/null)
|
||||
PROTOC := $(shell command -v protoc 2>/dev/null)
|
||||
VERSION := $(shell git describe --tags)
|
||||
IDENTIFIER := $(VERSION)-$(GOOS)-$(GOARCH)
|
||||
CLONE_URL=github.com/pilosa/pilosa
|
||||
|
|
@ -43,5 +44,15 @@ install: vendor
|
|||
go install $(LDFLAGS) $(FLAGS) $(CLONE_URL)/cmd/pilosa
|
||||
go install $(LDFLAGS) $(FLAGS) $(CLONE_URL)/cmd/pilosactl
|
||||
|
||||
.protoc-gen-gofast: vendor
|
||||
ifndef PROTOC
|
||||
$(error "protoc is not available please install protoc from https://github.com/google/protobuf/releases")
|
||||
endif
|
||||
go build -o .protoc-gen-gofast ./vendor/github.com/gogo/protobuf/protoc-gen-gofast
|
||||
cp ./.protoc-gen-gofast $(GOPATH)/bin/protoc-gen-gofast
|
||||
|
||||
generate: .protoc-gen-gofast
|
||||
go generate github.com/pilosa/pilosa/internal
|
||||
|
||||
docker:
|
||||
docker build -t pilosa:latest .
|
||||
|
|
|
|||
86
README.md
86
README.md
|
|
@ -100,22 +100,55 @@ Return a list of all databases and frames in the index:
|
|||
$ curl "http://127.0.0.1:15000/schema"
|
||||
```
|
||||
|
||||
### Database and Frame Schema
|
||||
|
||||
Before running a query, the corresponding database and frame must be created. Note that database and frame names can contain only lower case letters, numbers, dash (`-`), underscore (`_`) and dot (`.`).
|
||||
|
||||
You can create the database `sample-db` using:
|
||||
|
||||
```sh
|
||||
$ curl -XPOST "http://127.0.0.1:15000/db" \
|
||||
-d '{"db": "sample-db"}'
|
||||
```
|
||||
|
||||
Optionally, you can specify the column label on database creation:
|
||||
|
||||
```sh
|
||||
$ curl -XPOST "http://127.0.0.1:15000/db" \
|
||||
-d '{"db": "sample-db", "columnLabel": "user"}'
|
||||
```
|
||||
|
||||
The frame `collaboration` may be created using the following call:
|
||||
|
||||
```sh
|
||||
$ curl -XPOST "http://127.0.0.1:15000/frame" \
|
||||
-d '{"db": "sample-db", "frame": "collaboration"}'
|
||||
```
|
||||
|
||||
It is possible to specify the frame row label on frame creation:
|
||||
|
||||
```sh
|
||||
$ curl -XPOST "http://127.0.0.1:15000/frame" \
|
||||
-d '{"db": "sample-db", "frame": "collaboration"}, "options": {"rowLabel": "project"}}'
|
||||
```
|
||||
|
||||
### Queries
|
||||
|
||||
Queries to Pilosa require sending a POST request where the query itself is sent as POST data.
|
||||
You specify the database on which to perform the query with a URL argument `db=database-name`.
|
||||
|
||||
A query sent to database `exampleDB` will have the following format:
|
||||
In this section, we assume both the database `sample-db` with column label `user` and the frame `collaboration` with row label `project` was created.
|
||||
|
||||
A query sent to database `sample-db` will have the following format:
|
||||
|
||||
```sh
|
||||
$ curl -X POST "http://127.0.0.1:15000/query?db=exampleDB" -d 'Query()'
|
||||
$ curl -X POST "http://127.0.0.1:15000/query?db=sample-db" -d 'Query()'
|
||||
```
|
||||
|
||||
The `Query()` object referenced above should be made up of one or more of the query types listed below.
|
||||
So for example, a SetBit() query would look like this:
|
||||
```sh
|
||||
$ curl -X POST "http://127.0.0.1:15000/query?db=exampleDB" -d 'SetBit(id=10, frame="foo", profileID=1)'
|
||||
$ curl -X POST "http://127.0.0.1:15000/query?db=sample-db" -d 'SetBit(project=10, frame="collaboration", user=1)'
|
||||
```
|
||||
|
||||
Query results have the format `{"results":[]}`, where `results` is a list of results for each `Query()`. This
|
||||
|
|
@ -123,26 +156,26 @@ means that you can provide multiple `Query()` objects with each HTTP request and
|
|||
the results of all of the queries.
|
||||
|
||||
```sh
|
||||
$ curl -X POST "http://127.0.0.1:15000/query?db=exampleDB" -d 'Query() Query() Query()'
|
||||
$ curl -X POST "http://127.0.0.1:15000/query?db=sample-db" -d 'Query() Query() Query()'
|
||||
```
|
||||
|
||||
---
|
||||
#### SetBit()
|
||||
```
|
||||
SetBit(id=10, frame="foo", profileID=1)
|
||||
SetBit(project=10, frame="collaboration", user=1)
|
||||
```
|
||||
A return value of `{"results":[true]}` indicates that the bit was toggled from 0 to 1.
|
||||
A return value of `{"results":[false]}` indicates that the bit was already set to 1 and therefore nothing changed.
|
||||
|
||||
SetBit accepts an optional `timestamp` field:
|
||||
```
|
||||
SetBit(id=10, frame=f, profileID=2, timestamp="2016-12-11T10:09:07")
|
||||
SetBit(project=10, frame="collaboration", user=2, timestamp="2016-12-11T10:09:07")
|
||||
```
|
||||
|
||||
---
|
||||
#### ClearBit()
|
||||
```
|
||||
ClearBit(id=10, frame="foo", profileID=1)
|
||||
ClearBit(project=10, frame="collaboration", user=1)
|
||||
```
|
||||
A return value of `{"results":[true]}` indicates that the bit was toggled from 1 to 0.
|
||||
A return value of `{"results":[false]}` indicates that the bit was already set to 0 and therefore nothing changed.
|
||||
|
|
@ -150,7 +183,7 @@ A return value of `{"results":[false]}` indicates that the bit was already set t
|
|||
---
|
||||
#### SetBitmapAttrs()
|
||||
```
|
||||
SetBitmapAttrs(id=10, frame="foo", category=123, color="blue", happy=true)
|
||||
SetBitmapAttrs(project=10, frame="collaboration", stars=123, url="http://projects.pilosa.com/10", active=true)
|
||||
```
|
||||
Returns `{"results":[null]}`
|
||||
|
||||
|
|
@ -158,7 +191,7 @@ Returns `{"results":[null]}`
|
|||
#### SetProfileAttrs()
|
||||
---
|
||||
```
|
||||
SetProfileAttrs(id=10, category=123, color="blue", happy=true)
|
||||
SetProfileAttrs(user=10, friends=123, username="mrpi", active=true)
|
||||
```
|
||||
|
||||
Returns `{"results":[null]}`
|
||||
|
|
@ -166,20 +199,20 @@ Returns `{"results":[null]}`
|
|||
---
|
||||
#### Bitmap()
|
||||
```
|
||||
Bitmap(id=10, frame="foo")
|
||||
Bitmap(project=10, frame="collaboration")
|
||||
```
|
||||
Returns `{"results":[{"attrs":{"category":123,"color":"blue","happy":true},"bits":[1,2]}]}` where `attrs` are the
|
||||
Returns `{"results":[{"attrs":{"stars":123, "url":"http://projects.pilosa.com/10", "active":true},"bits":[1,2]}]}` where `attrs` are the
|
||||
attributes set using `SetBitmapAttrs()` and `bits` are the bits set using `SetBit()`.
|
||||
|
||||
In order to return profile attributes attached to the profiles of a bitmap, add `&profiles=true` to the query string. Sample response:
|
||||
```
|
||||
{"results":[{"attrs":{},"bits":[10]}],"profiles":[{"id":10,"attrs":{"category":123,"color":"blue","happy":true}}]}
|
||||
{"results":[{"attrs":{},"bits":[10]}],"profiles":[{"user":10,"attrs":{"friends":123, "username":"mrpi", "active":true}}]}
|
||||
```
|
||||
|
||||
---
|
||||
#### Union()
|
||||
```
|
||||
Union(Bitmap(id=10, frame="foo"), Bitmap(id=20, frame="foo")))
|
||||
Union(Bitmap(project=10, frame="collaboration"), Bitmap(project=20, frame="collaboration")))
|
||||
```
|
||||
Returns a result set similar to that of a `Bitmap()` query, only the `attrs` dictionary will be empty: `{"results":[{"attrs":{},"bits":[1,2]}]}`.
|
||||
Note that a `Union()` query can be nested within other queries anywhere that you would otherwise provide a `Bitmap()`.
|
||||
|
|
@ -187,7 +220,7 @@ Note that a `Union()` query can be nested within other queries anywhere that you
|
|||
---
|
||||
#### Intersect()
|
||||
```
|
||||
Intersect(Bitmap(id=10, frame="foo"), Bitmap(id=20, frame="foo")))
|
||||
Intersect(Bitmap(project=10, frame="collaboration"), Bitmap(project=20, frame="collaboration")))
|
||||
```
|
||||
Returns a result set similar to that of a `Bitmap()` query, only the `attrs` dictionary will be empty: `{"results":[{"attrs":{},"bits":[1]}]}`.
|
||||
Note that an `Intersect()` query can be nested within other queries anywhere that you would otherwise provide a `Bitmap()`.
|
||||
|
|
@ -195,7 +228,7 @@ Note that an `Intersect()` query can be nested within other queries anywhere tha
|
|||
---
|
||||
#### Difference()
|
||||
```
|
||||
Difference(Bitmap(id=10, frame="foo"), Bitmap(id=20, frame="foo")))
|
||||
Difference(Bitmap(project=10, frame="collaboration"), Bitmap(project=20, frame="collaboration")))
|
||||
```
|
||||
`Difference()` represents all of the bits that are set in the first `Bitmap()` but are not set in the second `Bitmap()`. It returns a result set similar to that of a `Bitmap()` query, only the `attrs` dictionary will be empty: `{"results":[{"attrs":{},"bits":[2]}]}`.
|
||||
Note that a `Difference()` query can be nested within other queries anywhere that you would otherwise provide a `Bitmap()`.
|
||||
|
|
@ -203,35 +236,38 @@ Note that a `Difference()` query can be nested within other queries anywhere tha
|
|||
---
|
||||
#### Count()
|
||||
```
|
||||
Count(Bitmap(id=10, frame="foo"))
|
||||
Count(Bitmap(project=10, frame="collaboration"))
|
||||
```
|
||||
Returns the count of the number of bits set in `Bitmap()`: `{"results":[28]}`
|
||||
|
||||
---
|
||||
#### Range()
|
||||
```
|
||||
Range(id=10, frame="foo", start="1970-01-01T00:00", end="2000-01-02T03:04")
|
||||
Range(project=10, frame="collaboration", start="1970-01-01T00:00", end="2000-01-02T03:04")
|
||||
```
|
||||
|
||||
---
|
||||
#### TopN()
|
||||
```
|
||||
TopN(frame="bar", n=20)
|
||||
TopN(frame="geo")
|
||||
```
|
||||
Returns the top 20 Bitmaps from frame `bar`.
|
||||
Returns all Bitmaps in the cache from frame `geo` sorted by the count of bits.
|
||||
|
||||
```
|
||||
TopN(Bitmap(id=10, frame="foo"), frame="bar", n=20)
|
||||
TopN(frame="geo", n=20)
|
||||
```
|
||||
Returns the top 20 Bitmaps from `bar` sorted by the count of bits in the intersection with `Bitmap(id=10)`.
|
||||
|
||||
Returns the top 20 Bitmaps from frame `geo`.
|
||||
|
||||
```
|
||||
TopN(Bitmap(id=10, frame="foo"), frame="bar", n=20, field="category", [81,82])
|
||||
TopN(Bitmap(project=10, frame="collaboration"), frame="geo", n=20)
|
||||
```
|
||||
Returns the top 20 Bitmaps from `geo` sorted by the count of bits in the intersection with `Bitmap(project=10)`.
|
||||
|
||||
Returns the top 20 Bitmaps from `bar`in attribute `category` with values `81 or
|
||||
82` sorted by the count of bits in the intersection with `Bitmap(id=10)`.
|
||||
```
|
||||
TopN(Bitmap(project=10, frame="collaboration"), frame="geo", n=20, field="category", [81,82])
|
||||
```
|
||||
Returns the top 20 Bitmaps from `geo`in attribute `category` with values `81 or
|
||||
82` sorted by the count of bits in the intersection with `Bitmap(project=10)`.
|
||||
|
||||
## Development
|
||||
|
||||
|
|
|
|||
11
attr.go
11
attr.go
|
|
@ -22,6 +22,7 @@ const (
|
|||
AttrTypeString = 1
|
||||
AttrTypeUint = 2
|
||||
AttrTypeBool = 3
|
||||
AttrTypeFloat = 4
|
||||
)
|
||||
|
||||
// AttrStore represents a storage layer for attributes.
|
||||
|
|
@ -265,11 +266,9 @@ func txUpdateAttrs(tx *bolt.Tx, id uint64, m map[string]interface{}) (map[string
|
|||
attr[k] = uint64(v)
|
||||
case uint:
|
||||
attr[k] = uint64(v)
|
||||
case float64:
|
||||
attr[k] = uint64(v)
|
||||
case int64:
|
||||
attr[k] = uint64(v)
|
||||
case string, uint64, bool:
|
||||
case string, uint64, bool, float64:
|
||||
attr[k] = v
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid attr type: %T", v)
|
||||
|
|
@ -318,8 +317,8 @@ func encodeAttr(key string, value interface{}) *internal.Attr {
|
|||
pb.Type = AttrTypeString
|
||||
pb.StringValue = value
|
||||
case float64:
|
||||
pb.Type = AttrTypeUint
|
||||
pb.UintValue = uint64(value)
|
||||
pb.Type = AttrTypeFloat
|
||||
pb.FloatValue = value
|
||||
case uint64:
|
||||
pb.Type = AttrTypeUint
|
||||
pb.UintValue = value
|
||||
|
|
@ -342,6 +341,8 @@ func decodeAttr(attr *internal.Attr) (key string, value interface{}) {
|
|||
return attr.Key, attr.UintValue
|
||||
case AttrTypeBool:
|
||||
return attr.Key, attr.BoolValue
|
||||
case AttrTypeFloat:
|
||||
return attr.Key, attr.FloatValue
|
||||
default:
|
||||
return attr.Key, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,11 +122,12 @@ func (m *Profile) GetAttrs() []*Attr {
|
|||
}
|
||||
|
||||
type Attr struct {
|
||||
Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"`
|
||||
Type uint64 `protobuf:"varint,2,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
StringValue string `protobuf:"bytes,3,opt,name=StringValue,proto3" json:"StringValue,omitempty"`
|
||||
UintValue uint64 `protobuf:"varint,4,opt,name=UintValue,proto3" json:"UintValue,omitempty"`
|
||||
BoolValue bool `protobuf:"varint,5,opt,name=BoolValue,proto3" json:"BoolValue,omitempty"`
|
||||
Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"`
|
||||
Type uint64 `protobuf:"varint,2,opt,name=Type,proto3" json:"Type,omitempty"`
|
||||
StringValue string `protobuf:"bytes,3,opt,name=StringValue,proto3" json:"StringValue,omitempty"`
|
||||
UintValue uint64 `protobuf:"varint,4,opt,name=UintValue,proto3" json:"UintValue,omitempty"`
|
||||
BoolValue bool `protobuf:"varint,5,opt,name=BoolValue,proto3" json:"BoolValue,omitempty"`
|
||||
FloatValue float64 `protobuf:"fixed64,6,opt,name=FloatValue,proto3" json:"FloatValue,omitempty"`
|
||||
}
|
||||
|
||||
func (m *Attr) Reset() { *m = Attr{} }
|
||||
|
|
@ -554,6 +555,11 @@ func (m *Attr) MarshalTo(dAtA []byte) (int, error) {
|
|||
}
|
||||
i++
|
||||
}
|
||||
if m.FloatValue != 0 {
|
||||
dAtA[i] = 0x31
|
||||
i++
|
||||
i = encodeFixed64Internal(dAtA, i, uint64(math.Float64bits(float64(m.FloatValue))))
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
|
|
@ -1171,6 +1177,9 @@ func (m *Attr) Size() (n int) {
|
|||
if m.BoolValue {
|
||||
n += 2
|
||||
}
|
||||
if m.FloatValue != 0 {
|
||||
n += 9
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
|
@ -2188,6 +2197,24 @@ func (m *Attr) Unmarshal(dAtA []byte) error {
|
|||
}
|
||||
}
|
||||
m.BoolValue = bool(v != 0)
|
||||
case 6:
|
||||
if wireType != 1 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field FloatValue", wireType)
|
||||
}
|
||||
var v uint64
|
||||
if (iNdEx + 8) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += 8
|
||||
v = uint64(dAtA[iNdEx-8])
|
||||
v |= uint64(dAtA[iNdEx-7]) << 8
|
||||
v |= uint64(dAtA[iNdEx-6]) << 16
|
||||
v |= uint64(dAtA[iNdEx-5]) << 24
|
||||
v |= uint64(dAtA[iNdEx-4]) << 32
|
||||
v |= uint64(dAtA[iNdEx-3]) << 40
|
||||
v |= uint64(dAtA[iNdEx-2]) << 48
|
||||
v |= uint64(dAtA[iNdEx-1]) << 56
|
||||
m.FloatValue = float64(math.Float64frombits(v))
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipInternal(dAtA[iNdEx:])
|
||||
|
|
@ -3911,51 +3938,51 @@ var (
|
|||
func init() { proto.RegisterFile("internal.proto", fileDescriptorInternal) }
|
||||
|
||||
var fileDescriptorInternal = []byte{
|
||||
// 721 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x55, 0xcb, 0x6a, 0x14, 0x4d,
|
||||
0x14, 0xfe, 0x6b, 0xba, 0x7b, 0x2e, 0x67, 0x92, 0x61, 0x52, 0xcc, 0xff, 0xd3, 0x84, 0x9f, 0x61,
|
||||
0x28, 0x14, 0x06, 0xc1, 0x04, 0xe2, 0x46, 0x44, 0x10, 0x7b, 0x66, 0x24, 0x83, 0x26, 0x24, 0x95,
|
||||
0xe8, 0xce, 0x45, 0x25, 0x29, 0x93, 0x26, 0x7d, 0x19, 0xab, 0xab, 0xd5, 0x59, 0xba, 0x70, 0xe3,
|
||||
0x13, 0x88, 0x3e, 0x81, 0x6f, 0xe2, 0xd2, 0x47, 0x90, 0xf8, 0x22, 0x52, 0x97, 0xbe, 0x44, 0x31,
|
||||
0x66, 0xe1, 0xae, 0xbf, 0xef, 0xd4, 0x39, 0xf5, 0x9d, 0x5b, 0x35, 0xf4, 0xc2, 0x44, 0x72, 0x91,
|
||||
0xb0, 0x68, 0x63, 0x21, 0x52, 0x99, 0xe2, 0x76, 0x81, 0xc9, 0x36, 0x34, 0xa6, 0x01, 0x1e, 0x41,
|
||||
0xf7, 0x30, 0x8c, 0xf9, 0x7e, 0xce, 0x12, 0x99, 0xc7, 0x3e, 0x1a, 0xa1, 0x71, 0x87, 0xd6, 0x29,
|
||||
0x75, 0x62, 0x92, 0x46, 0x79, 0x9c, 0x3c, 0x61, 0x47, 0x3c, 0xf2, 0x1b, 0xe6, 0x44, 0x8d, 0x22,
|
||||
0x33, 0xf0, 0x1e, 0x09, 0x16, 0xf3, 0x6b, 0x04, 0x5b, 0x87, 0x36, 0x4d, 0x5f, 0xd7, 0x23, 0x95,
|
||||
0x98, 0x04, 0xd0, 0x0c, 0x42, 0x19, 0xb3, 0x05, 0xc6, 0xe0, 0x06, 0xa1, 0xcc, 0x7c, 0x34, 0x72,
|
||||
0xc6, 0x2e, 0xd5, 0xdf, 0xf8, 0x06, 0x78, 0x0f, 0xa5, 0x14, 0x99, 0xdf, 0x18, 0x39, 0xe3, 0xee,
|
||||
0x56, 0x6f, 0xa3, 0x4c, 0x4c, 0xd1, 0xd4, 0x18, 0xc9, 0x06, 0xb8, 0x7b, 0x2c, 0x14, 0xb8, 0x0f,
|
||||
0xce, 0x63, 0xbe, 0xd4, 0x0a, 0x5c, 0xaa, 0x3e, 0xf1, 0x00, 0xbc, 0x49, 0x9a, 0x27, 0x52, 0x5f,
|
||||
0xeb, 0x52, 0x03, 0xc8, 0x73, 0x70, 0x82, 0x50, 0x2a, 0x59, 0xe6, 0xea, 0xf9, 0xd4, 0xfa, 0x94,
|
||||
0x18, 0xff, 0x0f, 0x9d, 0x3d, 0x91, 0xbe, 0x08, 0x23, 0x3e, 0x9f, 0x5a, 0xe7, 0x8a, 0x50, 0x56,
|
||||
0x95, 0x5f, 0x26, 0x59, 0xbc, 0xf0, 0x9d, 0x11, 0x1a, 0x3b, 0xb4, 0x22, 0xc8, 0x03, 0x68, 0xd9,
|
||||
0xa3, 0xb8, 0x07, 0x8d, 0x32, 0x78, 0x63, 0x3e, 0xbd, 0x66, 0x3e, 0xef, 0x11, 0xb8, 0xea, 0xab,
|
||||
0x9e, 0x50, 0xc7, 0x24, 0x84, 0xc1, 0x3d, 0x5c, 0x2e, 0xb8, 0x95, 0xa4, 0xbf, 0x55, 0x03, 0x0e,
|
||||
0xa4, 0x08, 0x93, 0xd3, 0x67, 0x2c, 0xca, 0xb9, 0xd6, 0xd3, 0xa1, 0x75, 0x4a, 0xe9, 0x7d, 0x1a,
|
||||
0x26, 0xd2, 0xd8, 0x5d, 0x93, 0x4d, 0x49, 0x28, 0x6b, 0x90, 0xa6, 0x91, 0xb1, 0x7a, 0x23, 0x34,
|
||||
0x6e, 0xd3, 0x8a, 0x20, 0x9b, 0xd0, 0x52, 0x5a, 0x76, 0xd8, 0xa2, 0x52, 0x8f, 0xae, 0x52, 0xff,
|
||||
0x11, 0xc1, 0xca, 0x7e, 0xce, 0xc5, 0x92, 0xf2, 0x97, 0x39, 0xcf, 0xa4, 0x2a, 0xc2, 0x34, 0xb0,
|
||||
0x49, 0xa8, 0xe9, 0x1b, 0x80, 0xa7, 0xed, 0x76, 0x16, 0x0c, 0xc0, 0xff, 0x41, 0xf3, 0x20, 0x0a,
|
||||
0x8f, 0x79, 0xe6, 0x3b, 0x7a, 0x00, 0x2c, 0x52, 0x5d, 0xb2, 0xd5, 0xcc, 0xb4, 0xf4, 0x36, 0x2d,
|
||||
0x31, 0xf6, 0xa1, 0x55, 0x8c, 0x9d, 0xa7, 0x63, 0x15, 0x50, 0x45, 0xa3, 0x3c, 0x4e, 0x25, 0xf7,
|
||||
0x9b, 0xda, 0xc7, 0x22, 0xf2, 0x16, 0xc1, 0xaa, 0x15, 0x97, 0x2d, 0xd2, 0x24, 0xe3, 0xaa, 0xc6,
|
||||
0x33, 0x21, 0x8a, 0x1a, 0xcf, 0x84, 0xc0, 0x9b, 0xd0, 0xa2, 0x3c, 0xcb, 0x23, 0x59, 0xb4, 0xe9,
|
||||
0xdf, 0x2a, 0xd1, 0xc2, 0x37, 0x8f, 0x24, 0x2d, 0x4e, 0xe1, 0xdb, 0x35, 0x89, 0x8e, 0xf6, 0x58,
|
||||
0xab, 0x3c, 0xac, 0xa5, 0x52, 0x4d, 0xde, 0x21, 0xe8, 0xd6, 0xe2, 0xe0, 0x71, 0xb1, 0x02, 0x5a,
|
||||
0x44, 0x77, 0xab, 0x5f, 0x39, 0x1b, 0x9e, 0x16, 0x2b, 0xb2, 0x02, 0x68, 0xd7, 0xb6, 0x1e, 0xed,
|
||||
0xaa, 0x76, 0xa8, 0xb1, 0x2f, 0xee, 0xac, 0xb5, 0x43, 0xd1, 0xd4, 0x18, 0x55, 0x8d, 0x26, 0x67,
|
||||
0x2c, 0x39, 0xe5, 0x27, 0xb6, 0x7c, 0x05, 0x24, 0x9f, 0x11, 0xac, 0xce, 0xe3, 0x45, 0x2a, 0xe4,
|
||||
0x15, 0x9d, 0xd2, 0x3b, 0x5e, 0x74, 0xca, 0x2c, 0xfc, 0x00, 0x3c, 0xdd, 0x1b, 0x3d, 0x69, 0x2e,
|
||||
0x35, 0x40, 0x4f, 0x91, 0xdd, 0x1e, 0xd5, 0x28, 0xd5, 0xc2, 0x8a, 0xc0, 0x43, 0x80, 0x72, 0x7d,
|
||||
0x32, 0xdf, 0xd3, 0xe6, 0x1a, 0xa3, 0xec, 0xe5, 0x02, 0x65, 0x7e, 0x73, 0xe4, 0x8c, 0x1d, 0x5a,
|
||||
0x63, 0x08, 0x81, 0x5e, 0x21, 0xf5, 0x77, 0x7d, 0x23, 0x27, 0xd0, 0x0f, 0xa2, 0xf4, 0xf8, 0x7c,
|
||||
0xca, 0x24, 0xfb, 0x1b, 0x19, 0x0d, 0xc0, 0xd3, 0xf1, 0xec, 0xc6, 0x18, 0x40, 0xf6, 0x61, 0xad,
|
||||
0x76, 0x8b, 0x15, 0x73, 0x29, 0x79, 0x74, 0x75, 0xf2, 0x8d, 0x9f, 0x93, 0x27, 0x37, 0xc1, 0x9b,
|
||||
0xb0, 0xe3, 0xb3, 0x3f, 0x84, 0x21, 0x9f, 0x10, 0xac, 0xed, 0xb0, 0x37, 0x66, 0x2f, 0xca, 0xab,
|
||||
0xb7, 0xa1, 0x53, 0x92, 0x76, 0x31, 0x6f, 0x55, 0x93, 0xf0, 0xcb, 0xf9, 0x8a, 0x99, 0x25, 0x52,
|
||||
0x2c, 0x69, 0xe5, 0xbc, 0x7e, 0x1f, 0x7a, 0x97, 0x8d, 0xaa, 0xc6, 0xe7, 0xd5, 0xfb, 0x73, 0x6e,
|
||||
0x1e, 0xd4, 0x57, 0xfa, 0x9d, 0xb0, 0x0f, 0xaa, 0x06, 0xf7, 0x1a, 0x77, 0x51, 0xd0, 0xff, 0x72,
|
||||
0x31, 0x44, 0x5f, 0x2f, 0x86, 0xe8, 0xdb, 0xc5, 0x10, 0x7d, 0xf8, 0x3e, 0xfc, 0xe7, 0xa8, 0xa9,
|
||||
0x7f, 0x3e, 0x77, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x47, 0xed, 0xb3, 0x8e, 0x06, 0x00,
|
||||
0x00,
|
||||
// 735 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x55, 0xcb, 0x6e, 0xd4, 0x4a,
|
||||
0x10, 0xbd, 0x3d, 0xb6, 0xe7, 0x51, 0x93, 0x8c, 0x26, 0xad, 0xb9, 0x57, 0x56, 0x74, 0x35, 0xb2,
|
||||
0x5a, 0xf7, 0x4a, 0x16, 0x12, 0x89, 0x14, 0x36, 0x08, 0x21, 0x21, 0x3c, 0x33, 0x51, 0x46, 0x90,
|
||||
0x28, 0xe9, 0x04, 0x76, 0x2c, 0x3a, 0x49, 0x93, 0x58, 0xf1, 0x63, 0xb0, 0xdb, 0xc0, 0x2c, 0x59,
|
||||
0xf0, 0x0f, 0x08, 0xbe, 0x00, 0xbe, 0x84, 0x25, 0x9f, 0x80, 0xc2, 0x8f, 0xa0, 0x7e, 0xf8, 0x11,
|
||||
0x10, 0x21, 0x0b, 0x76, 0xae, 0x53, 0x5d, 0xd5, 0x75, 0xfa, 0x54, 0x95, 0x61, 0x10, 0x26, 0x82,
|
||||
0x67, 0x09, 0x8b, 0x36, 0x16, 0x59, 0x2a, 0x52, 0xdc, 0x2d, 0x6d, 0xb2, 0x03, 0xad, 0x69, 0x80,
|
||||
0x3d, 0xe8, 0x1f, 0x85, 0x31, 0x3f, 0x28, 0x58, 0x22, 0x8a, 0xd8, 0x45, 0x1e, 0xf2, 0x7b, 0xb4,
|
||||
0x09, 0xc9, 0x13, 0x93, 0x34, 0x2a, 0xe2, 0xe4, 0x31, 0x3b, 0xe6, 0x91, 0xdb, 0xd2, 0x27, 0x1a,
|
||||
0x10, 0x99, 0x81, 0xb3, 0x9d, 0xb1, 0x98, 0xdf, 0x20, 0xd9, 0x3a, 0x74, 0x69, 0xfa, 0xaa, 0x99,
|
||||
0xa9, 0xb2, 0x49, 0x00, 0xed, 0x20, 0x14, 0x31, 0x5b, 0x60, 0x0c, 0x76, 0x10, 0x8a, 0xdc, 0x45,
|
||||
0x9e, 0xe5, 0xdb, 0x54, 0x7d, 0xe3, 0xff, 0xc0, 0x79, 0x28, 0x44, 0x96, 0xbb, 0x2d, 0xcf, 0xf2,
|
||||
0xfb, 0x5b, 0x83, 0x8d, 0x8a, 0x98, 0x84, 0xa9, 0x76, 0x92, 0x0d, 0xb0, 0xf7, 0x59, 0x98, 0xe1,
|
||||
0x21, 0x58, 0x8f, 0xf8, 0x52, 0x55, 0x60, 0x53, 0xf9, 0x89, 0x47, 0xe0, 0x4c, 0xd2, 0x22, 0x11,
|
||||
0xea, 0x5a, 0x9b, 0x6a, 0x83, 0x3c, 0x03, 0x2b, 0x08, 0x85, 0x2c, 0x4b, 0x5f, 0x3d, 0x9f, 0x9a,
|
||||
0x98, 0xca, 0xc6, 0xff, 0x42, 0x6f, 0x3f, 0x4b, 0x9f, 0x87, 0x11, 0x9f, 0x4f, 0x4d, 0x70, 0x0d,
|
||||
0x48, 0xaf, 0xe4, 0x97, 0x0b, 0x16, 0x2f, 0x5c, 0xcb, 0x43, 0xbe, 0x45, 0x6b, 0x80, 0x3c, 0x80,
|
||||
0x8e, 0x39, 0x8a, 0x07, 0xd0, 0xaa, 0x92, 0xb7, 0xe6, 0xd3, 0x1b, 0xf2, 0xf9, 0x84, 0xc0, 0x96,
|
||||
0x5f, 0x4d, 0x42, 0x3d, 0x4d, 0x08, 0x83, 0x7d, 0xb4, 0x5c, 0x70, 0x53, 0x92, 0xfa, 0x96, 0x02,
|
||||
0x1c, 0x8a, 0x2c, 0x4c, 0xce, 0x9e, 0xb2, 0xa8, 0xe0, 0xaa, 0x9e, 0x1e, 0x6d, 0x42, 0xb2, 0xde,
|
||||
0x27, 0x61, 0x22, 0xb4, 0xdf, 0xd6, 0x6c, 0x2a, 0x40, 0x7a, 0x83, 0x34, 0x8d, 0xb4, 0xd7, 0xf1,
|
||||
0x90, 0xdf, 0xa5, 0x35, 0x80, 0xc7, 0x00, 0xdb, 0x51, 0xca, 0x4c, 0x70, 0xdb, 0x43, 0x3e, 0xa2,
|
||||
0x0d, 0x84, 0x6c, 0x42, 0x47, 0xd6, 0xba, 0xcb, 0x16, 0x35, 0x3b, 0x74, 0x1d, 0xbb, 0xf7, 0x08,
|
||||
0x56, 0x0e, 0x0a, 0x9e, 0x2d, 0x29, 0x7f, 0x51, 0xf0, 0x5c, 0xc8, 0x47, 0x9a, 0x06, 0x86, 0xa4,
|
||||
0xec, 0xce, 0x11, 0x38, 0xca, 0x6f, 0x7a, 0x45, 0x1b, 0xf8, 0x1f, 0x68, 0x1f, 0x46, 0xe1, 0x09,
|
||||
0xcf, 0x5d, 0x4b, 0x35, 0x88, 0xb1, 0xa4, 0x8a, 0xe6, 0xb5, 0x73, 0x45, 0xad, 0x4b, 0x2b, 0x1b,
|
||||
0xbb, 0xd0, 0x29, 0xdb, 0xd2, 0x51, 0xb9, 0x4a, 0x53, 0x66, 0xa3, 0x3c, 0x4e, 0x85, 0x66, 0xd4,
|
||||
0xa5, 0xc6, 0x22, 0x6f, 0x10, 0xac, 0x9a, 0xe2, 0xf2, 0x45, 0x9a, 0xe4, 0x5c, 0x6a, 0x30, 0xcb,
|
||||
0xb2, 0x52, 0x83, 0x59, 0x96, 0xe1, 0x4d, 0xe8, 0x50, 0x9e, 0x17, 0x91, 0x28, 0x65, 0xfc, 0xbb,
|
||||
0x26, 0x5a, 0xc6, 0x16, 0x91, 0xa0, 0xe5, 0x29, 0x7c, 0xbb, 0x51, 0xa2, 0xa5, 0x22, 0xd6, 0xea,
|
||||
0x08, 0xe3, 0xa9, 0xab, 0x26, 0x6f, 0x11, 0xf4, 0x1b, 0x79, 0xb0, 0x5f, 0x8e, 0x88, 0x2a, 0xa2,
|
||||
0xbf, 0x35, 0xac, 0x83, 0x35, 0x4e, 0xcb, 0x11, 0x5a, 0x01, 0xb4, 0x67, 0x5a, 0x03, 0xed, 0x49,
|
||||
0x39, 0xe4, 0x58, 0x94, 0x77, 0x36, 0xe4, 0x90, 0x30, 0xd5, 0x4e, 0xf9, 0x46, 0x93, 0x73, 0x96,
|
||||
0x9c, 0xf1, 0x53, 0xf3, 0x7c, 0xa5, 0x49, 0x3e, 0x22, 0x58, 0x9d, 0xc7, 0x8b, 0x34, 0x13, 0xd7,
|
||||
0x28, 0xa5, 0x76, 0x40, 0xa9, 0x94, 0x5e, 0x08, 0x23, 0x70, 0x94, 0x36, 0xaa, 0x13, 0x6d, 0xaa,
|
||||
0x0d, 0xd5, 0x65, 0x66, 0xba, 0xa4, 0x50, 0x52, 0xc2, 0x1a, 0x90, 0x5d, 0x56, 0x8d, 0x57, 0xee,
|
||||
0x3a, 0xca, 0xdd, 0x40, 0xa4, 0xbf, 0x1a, 0xb0, 0xdc, 0x6d, 0x7b, 0x96, 0x6f, 0xd1, 0x06, 0x42,
|
||||
0x08, 0x0c, 0xca, 0x52, 0x7f, 0xa5, 0x1b, 0x39, 0x85, 0x61, 0x10, 0xa5, 0x27, 0x17, 0x53, 0x26,
|
||||
0xd8, 0x9f, 0x60, 0x34, 0x02, 0x47, 0xe5, 0x33, 0x13, 0xa5, 0x0d, 0x72, 0x00, 0x6b, 0x8d, 0x5b,
|
||||
0x4c, 0x31, 0x57, 0xc8, 0xa3, 0xeb, 0xc9, 0xb7, 0x7e, 0x24, 0x4f, 0xfe, 0x07, 0x67, 0xc2, 0x4e,
|
||||
0xce, 0x7f, 0x93, 0x86, 0x7c, 0x40, 0xb0, 0xb6, 0xcb, 0x5e, 0xeb, 0xb9, 0xa8, 0xae, 0xde, 0x81,
|
||||
0x5e, 0x05, 0x9a, 0xc1, 0xbc, 0x55, 0x77, 0xc2, 0x4f, 0xe7, 0x6b, 0x64, 0x96, 0x88, 0x6c, 0x49,
|
||||
0xeb, 0xe0, 0xf5, 0xfb, 0x30, 0xb8, 0xea, 0x94, 0x6f, 0x7c, 0x51, 0xef, 0xa7, 0x0b, 0xbd, 0x70,
|
||||
0x5f, 0xaa, 0x45, 0x61, 0x16, 0xae, 0x32, 0xee, 0xb5, 0xee, 0xa2, 0x60, 0xf8, 0xf9, 0x72, 0x8c,
|
||||
0xbe, 0x5c, 0x8e, 0xd1, 0xd7, 0xcb, 0x31, 0x7a, 0xf7, 0x6d, 0xfc, 0xd7, 0x71, 0x5b, 0xfd, 0x9c,
|
||||
0xee, 0x7c, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xb6, 0x22, 0xbf, 0xb0, 0xae, 0x06, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ message Attr {
|
|||
string StringValue = 3;
|
||||
uint64 UintValue = 4;
|
||||
bool BoolValue = 5;
|
||||
double FloatValue = 6;
|
||||
}
|
||||
|
||||
message AttrMap {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package pilosa
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"github.com/pilosa/pilosa/internal"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// System errors.
|
||||
|
|
|
|||
|
|
@ -168,12 +168,18 @@ func (p *Parser) parseArgs() (map[string]interface{}, error) {
|
|||
}
|
||||
case STRING:
|
||||
value = lit
|
||||
case NUMBER:
|
||||
case INTEGER:
|
||||
v, err := strconv.ParseUint(lit, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value = v
|
||||
case FLOAT:
|
||||
v, err := strconv.ParseFloat(lit, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value = v
|
||||
case LBRACK:
|
||||
v, err := p.parseList()
|
||||
if err != nil {
|
||||
|
|
@ -219,7 +225,7 @@ func (p *Parser) parseList() ([]interface{}, error) {
|
|||
}
|
||||
case STRING:
|
||||
values = append(values, lit)
|
||||
case NUMBER:
|
||||
case INTEGER:
|
||||
v, err := strconv.ParseUint(lit, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -80,6 +80,26 @@ func TestParser_Parse(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
// Parse with float arguments.
|
||||
t.Run("WithFloatArgs", func(t *testing.T) {
|
||||
q, err := pql.ParseString(`MyCall( key=12.25, foo= 13.167, bar=2., baz=0.9)`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !reflect.DeepEqual(q.Calls[0],
|
||||
&pql.Call{
|
||||
Name: "MyCall",
|
||||
Args: map[string]interface{}{
|
||||
"key": 12.25,
|
||||
"foo": 13.167,
|
||||
"bar": 2.,
|
||||
"baz": 0.9,
|
||||
},
|
||||
},
|
||||
) {
|
||||
t.Fatalf("unexpected call: %#v", q.Calls[0])
|
||||
}
|
||||
})
|
||||
|
||||
// Parse with both child calls and arguments.
|
||||
t.Run("ChildrenAndArguments", func(t *testing.T) {
|
||||
q, err := pql.ParseString(`TopN(Bitmap(id=100, frame=other), frame=f, n=3)`)
|
||||
|
|
|
|||
|
|
@ -140,20 +140,26 @@ func (s *Scanner) scanIdent() (tok Token, pos Pos, lit string) {
|
|||
return IDENT, pos, lit
|
||||
}
|
||||
|
||||
// scanNumber consumes consecutive integer digits.
|
||||
// scanNumber consumes consecutive digits and up to one '.' character.
|
||||
func (s *Scanner) scanNumber() (tok Token, pos Pos, lit string) {
|
||||
pos = s.pos
|
||||
tok = INTEGER
|
||||
|
||||
var buf bytes.Buffer
|
||||
var seenDot bool
|
||||
for {
|
||||
ch := s.read()
|
||||
if !isDigit(ch) {
|
||||
if !isDigit(ch) && (seenDot || ch != '.') {
|
||||
s.unread()
|
||||
break
|
||||
}
|
||||
if ch == '.' {
|
||||
seenDot = true
|
||||
tok = FLOAT
|
||||
}
|
||||
buf.WriteRune(ch)
|
||||
}
|
||||
return NUMBER, pos, buf.String()
|
||||
return tok, pos, buf.String()
|
||||
}
|
||||
|
||||
// scanString consumes a single-quoted or double-quoted string.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ func TestScanner_Scan(t *testing.T) {
|
|||
{s: `]`, tok: pql.RBRACK, lit: `]`},
|
||||
|
||||
{s: `foo`, tok: pql.IDENT, lit: `foo`},
|
||||
{s: `100`, tok: pql.NUMBER, lit: `100`},
|
||||
{s: `100`, tok: pql.INTEGER, lit: `100`},
|
||||
{s: `100.3`, tok: pql.FLOAT, lit: `100.3`},
|
||||
|
||||
{s: `all`, tok: pql.ALL, lit: `all`},
|
||||
{s: `ALL`, tok: pql.ALL, lit: `ALL`}, // case insensitive
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ const (
|
|||
IDENT // main
|
||||
STRING // "foo"
|
||||
BADSTRING // bad escape or unclosed string
|
||||
NUMBER // 12345
|
||||
INTEGER // 12345
|
||||
FLOAT // 100.2
|
||||
literal_end
|
||||
|
||||
keyword_beg
|
||||
|
|
@ -35,8 +36,9 @@ var tokens = [...]string{
|
|||
EOF: "EOF",
|
||||
WS: "WS",
|
||||
|
||||
IDENT: "IDENT",
|
||||
NUMBER: "NUMBER",
|
||||
IDENT: "IDENT",
|
||||
INTEGER: "INTEGER",
|
||||
FLOAT: "FLOAT",
|
||||
|
||||
ALL: "ALL",
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue