mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-10-09 12:27:52 +00:00
fuzz testing and bug fixes
This commit is contained in:
parent
2ddc2ceeeb
commit
1e05920742
86 changed files with 1072 additions and 686 deletions
|
|
@ -653,7 +653,7 @@ func TestHandler_Query_ErrParse(t *testing.T) {
|
|||
h.ServeHTTP(w, test.MustNewHTTPRequest("POST", "/index/idx0/query?slices=0,1", strings.NewReader("bad_fn(")))
|
||||
if w.Code != gohttp.StatusBadRequest {
|
||||
t.Fatalf("unexpected status code: %d", w.Code)
|
||||
} else if body := w.Body.String(); body != `{"error":"parsing: parsing: \nparse error near PegText (line 1 symbol 1 - line 1 symbol 4):\n\"bad\"\n"}`+"\n" {
|
||||
} else if body := w.Body.String(); body != `{"error":"parsing: parsing: \nparse error near open (line 1 symbol 7 - line 1 symbol 8):\n\"(\"\n"}`+"\n" {
|
||||
t.Fatalf("unexpected body: \n%s", body)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,11 +72,8 @@ func (q *Query) addVal(val interface{}) {
|
|||
return
|
||||
}
|
||||
if q.lastCond != ILLEGAL {
|
||||
if val != nil || q.lastCond != NEQ {
|
||||
panic(fmt.Sprintf("can't add val %s with condition %s", val, q.lastCond))
|
||||
}
|
||||
call.Args[q.lastField] = &Condition{
|
||||
Op: NEQ,
|
||||
Op: q.lastCond,
|
||||
Value: val,
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
8
pql/fuzz/README.txt
Normal file
8
pql/fuzz/README.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
See https://github.com/dvyukov/go-fuzz
|
||||
|
||||
|
||||
Quickstart:
|
||||
|
||||
go get -u github.com/dvyukov/go-fuzz/...
|
||||
go-fuzz-build github.com/pilosa/pilosa/pql
|
||||
go-fuzz -bin=./pql-fuzz.zip -workdir=$GOPATH/src/github.com/pilosa/pilosa/pql/fuzz
|
||||
|
|
@ -0,0 +1 @@
|
|||
e(rT03
|
||||
|
|
@ -0,0 +1 @@
|
|||
e(d=f2002-01-01T03:00
|
||||
1
pql/fuzz/corpus/0eb3a86490e4bb0a031ed5c33b2f3a8c90785746
Normal file
1
pql/fuzz/corpus/0eb3a86490e4bb0a031ed5c33b2f3a8c90785746
Normal file
|
|
@ -0,0 +1 @@
|
|||
e(other!=-2)
|
||||
1
pql/fuzz/corpus/1
Normal file
1
pql/fuzz/corpus/1
Normal file
|
|
@ -0,0 +1 @@
|
|||
Bitmap()
|
||||
1
pql/fuzz/corpus/10
Normal file
1
pql/fuzz/corpus/10
Normal file
|
|
@ -0,0 +1 @@
|
|||
Bitmap(row=10, field=f)
|
||||
1
pql/fuzz/corpus/11
Normal file
1
pql/fuzz/corpus/11
Normal file
|
|
@ -0,0 +1 @@
|
|||
Difference(Bitmap(row=10), Bitmap(row=11))
|
||||
1
pql/fuzz/corpus/11f674c766421132650bcbf8ccc265a013a3409f
Normal file
1
pql/fuzz/corpus/11f674c766421132650bcbf8ccc265a013a3409f
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(foo<0)
|
||||
1
pql/fuzz/corpus/12
Normal file
1
pql/fuzz/corpus/12
Normal file
|
|
@ -0,0 +1 @@
|
|||
Difference()
|
||||
1
pql/fuzz/corpus/13
Normal file
1
pql/fuzz/corpus/13
Normal file
|
|
@ -0,0 +1 @@
|
|||
Intersect(Bitmap(row=10), Bitmap(row=11))
|
||||
1
pql/fuzz/corpus/131cfdaafbd04db9dd2aa37fb23a656500ed1333
Normal file
1
pql/fuzz/corpus/131cfdaafbd04db9dd2aa37fb23a656500ed1333
Normal file
|
|
@ -0,0 +1 @@
|
|||
SV(invalid_column_name=10,f=100)
|
||||
1
pql/fuzz/corpus/14
Normal file
1
pql/fuzz/corpus/14
Normal file
|
|
@ -0,0 +1 @@
|
|||
Intersect()
|
||||
1
pql/fuzz/corpus/15
Normal file
1
pql/fuzz/corpus/15
Normal file
|
|
@ -0,0 +1 @@
|
|||
Union(Bitmap(row=10), Bitmap(row=11))
|
||||
1
pql/fuzz/corpus/16
Normal file
1
pql/fuzz/corpus/16
Normal file
|
|
@ -0,0 +1 @@
|
|||
Union()
|
||||
1
pql/fuzz/corpus/17
Normal file
1
pql/fuzz/corpus/17
Normal file
|
|
@ -0,0 +1 @@
|
|||
Xor(Bitmap(row=10), Bitmap(row=11))
|
||||
1
pql/fuzz/corpus/18
Normal file
1
pql/fuzz/corpus/18
Normal file
|
|
@ -0,0 +1 @@
|
|||
Count(Bitmap(row=10, field=f))
|
||||
1
pql/fuzz/corpus/19
Normal file
1
pql/fuzz/corpus/19
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetBit(row=11, field=f, col=1)
|
||||
1
pql/fuzz/corpus/2
Normal file
1
pql/fuzz/corpus/2
Normal file
|
|
@ -0,0 +1 @@
|
|||
Union( Bitmap() , Count() )
|
||||
1
pql/fuzz/corpus/20
Normal file
1
pql/fuzz/corpus/20
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetValue(col=10, f=25)
|
||||
1
pql/fuzz/corpus/21
Normal file
1
pql/fuzz/corpus/21
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetValue(invalid_column_name=10, f=100)
|
||||
1
pql/fuzz/corpus/22
Normal file
1
pql/fuzz/corpus/22
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetRowAttrs(row=10, field=f, baz=123, bat=true)
|
||||
5
pql/fuzz/corpus/23
Normal file
5
pql/fuzz/corpus/23
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
SetBit(field=f, row=1, col=2, timestamp="1999-12-31T00:00")
|
||||
SetBit(field=f, row=1, col=7, timestamp="2002-01-01T02:00")
|
||||
|
||||
SetBit(field=f, row=1, col=2, timestamp="1999-12-30T00:00")
|
||||
|
||||
1
pql/fuzz/corpus/24
Normal file
1
pql/fuzz/corpus/24
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(row=1, field=f, start="1999-12-31T00:00", end="2002-01-01T03:00")
|
||||
2
pql/fuzz/corpus/25
Normal file
2
pql/fuzz/corpus/25
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
Range(foo == 20)
|
||||
1
pql/fuzz/corpus/26
Normal file
1
pql/fuzz/corpus/26
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(other != null)
|
||||
1
pql/fuzz/corpus/27
Normal file
1
pql/fuzz/corpus/27
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(foo != 20)
|
||||
1
pql/fuzz/corpus/2751bda09fe203e30e9d5f214f9425e2dface095
Normal file
1
pql/fuzz/corpus/2751bda09fe203e30e9d5f214f9425e2dface095
Normal file
|
|
@ -0,0 +1 @@
|
|||
N(p(d=0,l=other), d=f,n=3)
|
||||
1
pql/fuzz/corpus/28
Normal file
1
pql/fuzz/corpus/28
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(other != -20)
|
||||
1
pql/fuzz/corpus/29
Normal file
1
pql/fuzz/corpus/29
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(foo < 20)
|
||||
1
pql/fuzz/corpus/3
Normal file
1
pql/fuzz/corpus/3
Normal file
|
|
@ -0,0 +1 @@
|
|||
Count( Bitmap( id=100))
|
||||
1
pql/fuzz/corpus/30
Normal file
1
pql/fuzz/corpus/30
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(foo <= 20)
|
||||
1
pql/fuzz/corpus/31
Normal file
1
pql/fuzz/corpus/31
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetRowAttrs(row=10, field=f, baz=12.3, bat=.21, bak=-.27, zaz=-0.27 , q=0, zoo="0", do='0')
|
||||
1
pql/fuzz/corpus/338717d7ceeb78f7b8b864547fcb87cd62334783
Normal file
1
pql/fuzz/corpus/338717d7ceeb78f7b8b864547fcb87cd62334783
Normal file
|
|
@ -0,0 +1 @@
|
|||
t( p( ))
|
||||
1
pql/fuzz/corpus/33fae0740e470344699582c2c8c6f3825de66007
Normal file
1
pql/fuzz/corpus/33fae0740e470344699582c2c8c6f3825de66007
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetRowAttrs(row=10,field=f,baz=123,bat=true)
|
||||
2
pql/fuzz/corpus/374b9d8c1d285b57c3fe1f99b76472714cc2c69c
Normal file
2
pql/fuzz/corpus/374b9d8c1d285b57c3fe1f99b76472714cc2c69c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
e(o == 0)
|
||||
1
pql/fuzz/corpus/392027b3a650e05b0bc4ca185143138585702c5c
Normal file
1
pql/fuzz/corpus/392027b3a650e05b0bc4ca185143138585702c5c
Normal file
|
|
@ -0,0 +1 @@
|
|||
e(r!=-2)
|
||||
1
pql/fuzz/corpus/3c9cda1dd6ed289bdec524bb9f4995a9c175d656
Normal file
1
pql/fuzz/corpus/3c9cda1dd6ed289bdec524bb9f4995a9c175d656
Normal file
|
|
@ -0,0 +1 @@
|
|||
MyCall( y=-12.25, o= -13)
|
||||
1
pql/fuzz/corpus/4
Normal file
1
pql/fuzz/corpus/4
Normal file
|
|
@ -0,0 +1 @@
|
|||
MyCall( key= value, foo="bar", age = 12 , bool0=true, bool1=false, x=null )
|
||||
1
pql/fuzz/corpus/452308054231977c3f6e551b72437500215019b5
Normal file
1
pql/fuzz/corpus/452308054231977c3f6e551b72437500215019b5
Normal file
|
|
@ -0,0 +1 @@
|
|||
t(p(w=1,l=f))
|
||||
1
pql/fuzz/corpus/5
Normal file
1
pql/fuzz/corpus/5
Normal file
|
|
@ -0,0 +1 @@
|
|||
MyCall( key=12.25, foo= 13.167, bar=2., baz=0.9)
|
||||
1
pql/fuzz/corpus/57e5daa393a1de6405e0315abf57cf061bd5dc44
Normal file
1
pql/fuzz/corpus/57e5daa393a1de6405e0315abf57cf061bd5dc44
Normal file
|
|
@ -0,0 +1 @@
|
|||
e(row=1,field=f,start="1999-12-31T00:00",end="2002-01-01T03:00")
|
||||
1
pql/fuzz/corpus/597ed3d1cef06f73136921bdd89fc2916cdd287c
Normal file
1
pql/fuzz/corpus/597ed3d1cef06f73136921bdd89fc2916cdd287c
Normal file
|
|
@ -0,0 +1 @@
|
|||
MyCall(ke=foo, x =5, y >= 100, z >< [4,8], m != null)
|
||||
1
pql/fuzz/corpus/5e982cd2a4acb990e97675afabce72032c1d08ef
Normal file
1
pql/fuzz/corpus/5e982cd2a4acb990e97675afabce72032c1d08ef
Normal file
|
|
@ -0,0 +1 @@
|
|||
SetValue(invalid_column_name=10,f=100)
|
||||
1
pql/fuzz/corpus/5f6b6920de296ca3a34d3ee14477a9d623d4efc2
Normal file
1
pql/fuzz/corpus/5f6b6920de296ca3a34d3ee14477a9d623d4efc2
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(other!=null)
|
||||
1
pql/fuzz/corpus/6
Normal file
1
pql/fuzz/corpus/6
Normal file
|
|
@ -0,0 +1 @@
|
|||
MyCall( key=-12.25, foo= -13)
|
||||
1
pql/fuzz/corpus/6078ffa2c7287a2fdbb9bca63274a414fd7bc83d
Normal file
1
pql/fuzz/corpus/6078ffa2c7287a2fdbb9bca63274a414fd7bc83d
Normal file
|
|
@ -0,0 +1 @@
|
|||
tRowAttrs(row=1, field=f, baz=13,bat=true)
|
||||
|
|
@ -0,0 +1 @@
|
|||
e(w=:
|
||||
1
pql/fuzz/corpus/7
Normal file
1
pql/fuzz/corpus/7
Normal file
|
|
@ -0,0 +1 @@
|
|||
TopN(field="f", ids=[0,10,30])
|
||||
|
|
@ -0,0 +1 @@
|
|||
n(p() , C
|
||||
1
pql/fuzz/corpus/7282523da2bd624500932760375168ac6d95b08b
Normal file
1
pql/fuzz/corpus/7282523da2bd624500932760375168ac6d95b08b
Normal file
|
|
@ -0,0 +1 @@
|
|||
t(p(d=100))
|
||||
|
|
@ -0,0 +1 @@
|
|||
U(B(,C
|
||||
|
|
@ -0,0 +1 @@
|
|||
e(w=12002
|
||||
1
pql/fuzz/corpus/75dcc3426aa51753b37f34acaab56815ae00af91
Normal file
1
pql/fuzz/corpus/75dcc3426aa51753b37f34acaab56815ae00af91
Normal file
|
|
@ -0,0 +1 @@
|
|||
e(o <= 0)
|
||||
1
pql/fuzz/corpus/7cb88de80a430fd4c411e469ded68c8ec2f8fcd3
Normal file
1
pql/fuzz/corpus/7cb88de80a430fd4c411e469ded68c8ec2f8fcd3
Normal file
|
|
@ -0,0 +1 @@
|
|||
t(p(w=0), p(w=1))
|
||||
|
|
@ -0,0 +1 @@
|
|||
n(p(),C(
|
||||
1
pql/fuzz/corpus/8
Normal file
1
pql/fuzz/corpus/8
Normal file
|
|
@ -0,0 +1 @@
|
|||
TopN(Bitmap(id=100, field=other), field=f, n=3)
|
||||
1
pql/fuzz/corpus/80899f5b5670badaff1d2c1820ad1d6c5ece8bf9
Normal file
1
pql/fuzz/corpus/80899f5b5670badaff1d2c1820ad1d6c5ece8bf9
Normal file
|
|
@ -0,0 +1 @@
|
|||
C(y=12.25,o=13.167,r=2.,z=0.9)
|
||||
1
pql/fuzz/corpus/9
Normal file
1
pql/fuzz/corpus/9
Normal file
|
|
@ -0,0 +1 @@
|
|||
MyCall(key=foo, x == 12.25, y >= 100, z >< [4,8], m != null)
|
||||
1
pql/fuzz/corpus/9456f79011b99928233a5c43c89d9bcabc788a9d
Normal file
1
pql/fuzz/corpus/9456f79011b99928233a5c43c89d9bcabc788a9d
Normal file
|
|
@ -0,0 +1 @@
|
|||
t(p( ))
|
||||
|
|
@ -0,0 +1 @@
|
|||
e(invalid_column_name<0,f=0)
|
||||
1
pql/fuzz/corpus/9cbc01e0a28e963310a3e6b80eeb094a3de77c06
Normal file
1
pql/fuzz/corpus/9cbc01e0a28e963310a3e6b80eeb094a3de77c06
Normal file
|
|
@ -0,0 +1 @@
|
|||
tV(f=5)
|
||||
1
pql/fuzz/corpus/9f974590bac2e9aa23f6e93128263403ca9d109f
Normal file
1
pql/fuzz/corpus/9f974590bac2e9aa23f6e93128263403ca9d109f
Normal file
|
|
@ -0,0 +1 @@
|
|||
t(Ba(w=0,d=f))
|
||||
1
pql/fuzz/corpus/a5ef2ba5c1423d9d03d8293be378b48af8dee79e
Normal file
1
pql/fuzz/corpus/a5ef2ba5c1423d9d03d8293be378b48af8dee79e
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(o < 0)
|
||||
1
pql/fuzz/corpus/af209066ba9b25655fadd130ec30aa42f9a6c606
Normal file
1
pql/fuzz/corpus/af209066ba9b25655fadd130ec30aa42f9a6c606
Normal file
|
|
@ -0,0 +1 @@
|
|||
n()
|
||||
1
pql/fuzz/corpus/b9258eb89acc5c62232f5e482449cc155a215125
Normal file
1
pql/fuzz/corpus/b9258eb89acc5c62232f5e482449cc155a215125
Normal file
|
|
@ -0,0 +1 @@
|
|||
Intersect(Bitmap(row=10),Bitmap(row=11))
|
||||
1
pql/fuzz/corpus/c0d2d3099c28dc8b6e838f1d95a5fd314d6caff5
Normal file
1
pql/fuzz/corpus/c0d2d3099c28dc8b6e838f1d95a5fd314d6caff5
Normal file
|
|
@ -0,0 +1 @@
|
|||
Cl( k=-12.25, f= -13)
|
||||
1
pql/fuzz/corpus/c7b63c3044a6dd7981d72573a970e9f1ac42f5b4
Normal file
1
pql/fuzz/corpus/c7b63c3044a6dd7981d72573a970e9f1ac42f5b4
Normal file
|
|
@ -0,0 +1 @@
|
|||
e(o<0)
|
||||
1
pql/fuzz/corpus/cd414eb16b1530ef1b9aa16a3b60abc932c4ca6c
Normal file
1
pql/fuzz/corpus/cd414eb16b1530ef1b9aa16a3b60abc932c4ca6c
Normal file
|
|
@ -0,0 +1 @@
|
|||
Difference(Bitmap(row=10),Bitmap(row=11))
|
||||
|
|
@ -0,0 +1 @@
|
|||
j(w=10375035658,t=R)
|
||||
1
pql/fuzz/corpus/d4a4d133499f09ad2d91114f55ed7235e985f7fd
Normal file
1
pql/fuzz/corpus/d4a4d133499f09ad2d91114f55ed7235e985f7fd
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(other!=l)
|
||||
1
pql/fuzz/corpus/d5dd3b391afdce17c47a2644e536431e3b5b6825
Normal file
1
pql/fuzz/corpus/d5dd3b391afdce17c47a2644e536431e3b5b6825
Normal file
|
|
@ -0,0 +1 @@
|
|||
e(o<=0)
|
||||
|
|
@ -0,0 +1 @@
|
|||
e(w=T
|
||||
1
pql/fuzz/corpus/e2c94a638563108995f18d0daadb9d2bd8a5f0c6
Normal file
1
pql/fuzz/corpus/e2c94a638563108995f18d0daadb9d2bd8a5f0c6
Normal file
|
|
@ -0,0 +1 @@
|
|||
l(key=oo, x == 12.25, y >= 100, z >< [4,8], m != null)
|
||||
1
pql/fuzz/corpus/e373d8c28776b2d1c8740807ffbe46cdd0260f98
Normal file
1
pql/fuzz/corpus/e373d8c28776b2d1c8740807ffbe46cdd0260f98
Normal file
|
|
@ -0,0 +1 @@
|
|||
SB(ow=1, f=f, c=1)
|
||||
1
pql/fuzz/corpus/ee78db5d4e2231cadcf5957d169657ef4658c343
Normal file
1
pql/fuzz/corpus/ee78db5d4e2231cadcf5957d169657ef4658c343
Normal file
|
|
@ -0,0 +1 @@
|
|||
Setalue(invalidcolumnnamf=0)
|
||||
1
pql/fuzz/corpus/f1c3a3daa6e74cf6ba1b8a494a21a34aa2aab41d
Normal file
1
pql/fuzz/corpus/f1c3a3daa6e74cf6ba1b8a494a21a34aa2aab41d
Normal file
|
|
@ -0,0 +1 @@
|
|||
N(field="f",ids=[0,10,30])
|
||||
1
pql/fuzz/corpus/f8f3c39e99db75ff5c8772a9871185a821a75f29
Normal file
1
pql/fuzz/corpus/f8f3c39e99db75ff5c8772a9871185a821a75f29
Normal file
|
|
@ -0,0 +1 @@
|
|||
U( B() , C() )
|
||||
1
pql/fuzz/corpus/ff41d50e5926d166b2adc0596339201274509856
Normal file
1
pql/fuzz/corpus/ff41d50e5926d166b2adc0596339201274509856
Normal file
|
|
@ -0,0 +1 @@
|
|||
Range(r!=null)
|
||||
|
|
@ -190,5 +190,4 @@ func TestParser_Parse(t *testing.T) {
|
|||
t.Fatalf("unexpected call: %#v", q.Calls[0])
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) {
|
|||
return NEQ, pos, "!="
|
||||
}
|
||||
s.unread()
|
||||
return ASSIGN, pos, string(ch)
|
||||
return ILLEGAL, pos, string(ch)
|
||||
case '<':
|
||||
if next := s.read(); next == '=' {
|
||||
return LTE, pos, "<="
|
||||
|
|
|
|||
115
pql/parser_fuzz.go
Normal file
115
pql/parser_fuzz.go
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// +build gofuzz
|
||||
|
||||
package pql
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/pilosa/pilosa/pql/internal/oldpql"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
p1 := NewParser(bytes.NewReader(data))
|
||||
q1, err1 := p1.Parse()
|
||||
p2 := oldpql.NewParser(bytes.NewReader(data))
|
||||
q2, err2 := p2.Parse()
|
||||
if err1 != nil && err2 != nil {
|
||||
return 0 // both error - this is fine
|
||||
}
|
||||
if err1 != nil || err2 != nil {
|
||||
// error in one but not both - need to know this
|
||||
panic(fmt.Sprintf("Query: '%s' errored one but not both.\n%v\n%v\n", data, err1, err2))
|
||||
}
|
||||
|
||||
// if parsers got different results
|
||||
if err := queriesEqual(q1, q2); err != nil {
|
||||
panic(fmt.Sprintf(`Query: '%s' parsed, but got different results:
|
||||
Result New (string)
|
||||
%s
|
||||
Result New (hashv)
|
||||
%#v
|
||||
Result Old (string)
|
||||
%s
|
||||
Result Old (hashv)
|
||||
%#v
|
||||
err:
|
||||
%v
|
||||
`, data, q1, q1, q2, q2, err))
|
||||
}
|
||||
|
||||
// both queries parsed succesfully and got equivalent results
|
||||
return 1
|
||||
}
|
||||
|
||||
func queriesEqual(q1 *Query, q2 *oldpql.Query) (err error) {
|
||||
if q1.String() != q2.String() {
|
||||
defer func() {
|
||||
// golang black magic
|
||||
if err == nil {
|
||||
err = errors.New("string reps unequal")
|
||||
} else {
|
||||
err = errors.Wrap(err, "string reps unequal")
|
||||
}
|
||||
}()
|
||||
}
|
||||
if len(q1.Calls) != len(q2.Calls) {
|
||||
return errors.Errorf("call lengths unequal: %d and %d", len(q1.Calls), len(q2.Calls))
|
||||
}
|
||||
for i, c1 := range q1.Calls {
|
||||
c2 := q2.Calls[i]
|
||||
if err := callsEqual(c1, c2); err != nil {
|
||||
return errors.Wrapf(err, "calls at %d not equal", i)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func callsEqual(c1 *Call, c2 *oldpql.Call) error {
|
||||
if err := argsEqual(c1.Args, c2.Args); err != nil {
|
||||
return errors.Wrap(err, "args unequal")
|
||||
}
|
||||
if c1.Name != c2.Name {
|
||||
return errors.Errorf("names unequal '%s' != '%s'", c1.Name, c2.Name)
|
||||
}
|
||||
if len(c1.Children) != len(c2.Children) {
|
||||
return errors.Errorf("different child lengths %d and %d", len(c1.Children), len(c2.Children))
|
||||
}
|
||||
|
||||
for i, child1 := range c1.Children {
|
||||
child2 := c2.Children[i]
|
||||
if err := callsEqual(child1, child2); err != nil {
|
||||
return errors.Wrapf(err, "children at %d not equal", i)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func argsEqual(a1 map[string]interface{}, a2 map[string]interface{}) error {
|
||||
if len(a1) != len(a2) {
|
||||
return errors.Errorf("lengths unequal %d and %d", len(a1), len(a2))
|
||||
}
|
||||
|
||||
for k, v1 := range a1 {
|
||||
v2 := a1[k]
|
||||
if c1, ok := v1.(Condition); ok {
|
||||
if c2, ok := v2.(oldpql.Condition); ok {
|
||||
if int(c1.Op) != int(c2.Op) {
|
||||
return errors.Errorf("condition ops unequal %d %d", c1, c2)
|
||||
}
|
||||
if !reflect.DeepEqual(c1.Value, c2.Value) {
|
||||
return errors.Errorf("condition values unequal '%v' '%v'", c1.Value, c2.Value)
|
||||
}
|
||||
continue
|
||||
}
|
||||
return errors.Errorf("values at %s unequal '%v' '%v'", k, v1, v2)
|
||||
}
|
||||
if !reflect.DeepEqual(v1, v2) {
|
||||
return errors.Errorf("values at %s unequal '%v' '%v'", k, v1, v2)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
17
pql/pql.peg
17
pql/pql.peg
|
|
@ -6,10 +6,10 @@ type PQL Peg {
|
|||
|
||||
|
||||
Calls <- Call* !.
|
||||
Call <- newline* < [[A-Z]]+ > { p.startCall(buffer[begin:end] ) } open args close newline* { p.endCall() }
|
||||
args <- arg (comma args)? sp / sp
|
||||
arg <- ( Call
|
||||
/ field sp '=' sp value
|
||||
Call <- whitesp < IDENT > { p.startCall(buffer[begin:end] ) } open allargs comma? close whitesp { p.endCall() }
|
||||
allargs <- Call (comma Call)* (comma args)? / comma? args / sp
|
||||
args <- arg (comma args)? sp
|
||||
arg <- ( field sp '=' sp value
|
||||
/ field sp COND sp value
|
||||
)
|
||||
COND <- ( '><' { p.addBTWN() }
|
||||
|
|
@ -25,9 +25,9 @@ value <- ( item
|
|||
/ lbrack { p.startList() } list rbrack { p.endList() }
|
||||
)
|
||||
list <- item (comma list)?
|
||||
item <- ( 'null' { p.addVal(nil) }
|
||||
/ 'true' { p.addVal(true) }
|
||||
/ 'false' { p.addVal(false) }
|
||||
item <- ( 'null' &(comma / sp close) { p.addVal(nil) }
|
||||
/ 'true' &(comma / sp close) { p.addVal(true) }
|
||||
/ 'false' &(comma / sp close) { p.addVal(false) }
|
||||
/ < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(buffer[begin:end]) }
|
||||
/ < '-'? '.'[0-9]+ > { p.addNumVal(buffer[begin:end]) }
|
||||
/ < ([[A-Z]] / [0-9] / '-' / '_' / ':')+ > { p.addVal(buffer[begin:end]) }
|
||||
|
|
@ -44,4 +44,5 @@ sp <- ( ' ' / '\t' )*
|
|||
comma <- sp ',' sp
|
||||
lbrack <- '[' sp
|
||||
rbrack <- sp ']' sp
|
||||
newline <- sp '\n' sp
|
||||
whitesp <- ( ' ' / '\t' / '\n' )*
|
||||
IDENT <- [[A-Z]] ([[A-Z]] / [0-9] / '-' / '_' / '.')*
|
||||
1502
pql/pql.peg.go
1502
pql/pql.peg.go
File diff suppressed because it is too large
Load diff
|
|
@ -20,4 +20,27 @@ SetBit(Union(Zitmap(row==4), Intersect(Qitmap(blah>4), Ritmap(field="http://zoo9
|
|||
if err == nil {
|
||||
t.Fatalf("should have been an error because of the interior unescaped double quote")
|
||||
}
|
||||
|
||||
q, err := ParseString("TopN(Bitmap(id==other), field=f, n=0)")
|
||||
if err != nil {
|
||||
t.Fatalf("should have parsed: %v", err)
|
||||
}
|
||||
if q.String() != `TopN(Bitmap(id == "other"), field="f", n=0)` {
|
||||
t.Fatalf("Failed, got: %s", q)
|
||||
}
|
||||
|
||||
q, err = ParseString("C(a=falsen0)")
|
||||
if err != nil {
|
||||
t.Fatalf("falsen0 should have been parsed as a string")
|
||||
}
|
||||
|
||||
q, err = ParseString("Bitmap(row=4, did==other)")
|
||||
if err != nil {
|
||||
t.Fatalf("should have parsed: %v", err)
|
||||
}
|
||||
|
||||
if q.String() != `Bitmap(did == "other", row=4)` {
|
||||
t.Fatalf("got %s", q)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue