diff --git a/pubsub/example_test.go b/pubsub/example_test.go index 6597c858d..3eda7d32d 100644 --- a/pubsub/example_test.go +++ b/pubsub/example_test.go @@ -19,7 +19,7 @@ func TestExample(t *testing.T) { ctx := context.Background() ch := make(chan interface{}, 1) - err := s.Subscribe(ctx, "example-client", query.MustParse("abci.account.name=John"), ch) + err := s.Subscribe(ctx, "example-client", query.MustParse("abci.account.name='John'"), ch) require.NoError(t, err) err = s.PublishWithTags(ctx, "Tombstone", map[string]interface{}{"abci.account.name": "John"}) require.NoError(t, err) diff --git a/pubsub/pubsub_test.go b/pubsub/pubsub_test.go index 85b4b1e4b..7bf7b41f7 100644 --- a/pubsub/pubsub_test.go +++ b/pubsub/pubsub_test.go @@ -46,14 +46,14 @@ func TestDifferentClients(t *testing.T) { ctx := context.Background() ch1 := make(chan interface{}, 1) - err := s.Subscribe(ctx, "client-1", query.MustParse("tm.events.type=NewBlock"), ch1) + err := s.Subscribe(ctx, "client-1", query.MustParse("tm.events.type='NewBlock'"), ch1) require.NoError(t, err) err = s.PublishWithTags(ctx, "Iceman", map[string]interface{}{"tm.events.type": "NewBlock"}) require.NoError(t, err) assertReceive(t, "Iceman", ch1) ch2 := make(chan interface{}, 1) - err = s.Subscribe(ctx, "client-2", query.MustParse("tm.events.type=NewBlock AND abci.account.name=Igor"), ch2) + err = s.Subscribe(ctx, "client-2", query.MustParse("tm.events.type='NewBlock' AND abci.account.name='Igor'"), ch2) require.NoError(t, err) err = s.PublishWithTags(ctx, "Ultimo", map[string]interface{}{"tm.events.type": "NewBlock", "abci.account.name": "Igor"}) require.NoError(t, err) @@ -61,7 +61,7 @@ func TestDifferentClients(t *testing.T) { assertReceive(t, "Ultimo", ch2) ch3 := make(chan interface{}, 1) - err = s.Subscribe(ctx, "client-3", query.MustParse("tm.events.type=NewRoundStep AND abci.account.name=Igor AND abci.invoice.number = 10"), ch3) + err = s.Subscribe(ctx, "client-3", query.MustParse("tm.events.type='NewRoundStep' AND abci.account.name='Igor' AND abci.invoice.number = 10"), ch3) require.NoError(t, err) err = s.PublishWithTags(ctx, "Valeria Richards", map[string]interface{}{"tm.events.type": "NewRoundStep"}) require.NoError(t, err) @@ -75,7 +75,7 @@ func TestClientSubscribesTwice(t *testing.T) { defer s.Stop() ctx := context.Background() - q := query.MustParse("tm.events.type=NewBlock") + q := query.MustParse("tm.events.type='NewBlock'") ch1 := make(chan interface{}, 1) err := s.Subscribe(ctx, clientID, q, ch1) @@ -184,7 +184,7 @@ func benchmarkNClients(n int, b *testing.B) { for range ch { } }() - s.Subscribe(ctx, clientID, query.MustParse(fmt.Sprintf("abci.Account.Owner = Ivan AND abci.Invoices.Number = %d", i)), ch) + s.Subscribe(ctx, clientID, query.MustParse(fmt.Sprintf("abci.Account.Owner = 'Ivan' AND abci.Invoices.Number = %d", i)), ch) } b.ReportAllocs() @@ -200,7 +200,7 @@ func benchmarkNClientsOneQuery(n int, b *testing.B) { defer s.Stop() ctx := context.Background() - q := query.MustParse("abci.Account.Owner = Ivan AND abci.Invoices.Number = 1") + q := query.MustParse("abci.Account.Owner = 'Ivan' AND abci.Invoices.Number = 1") for i := 0; i < n; i++ { ch := make(chan interface{}) go func() { diff --git a/pubsub/query/parser_test.go b/pubsub/query/parser_test.go index 194966664..165ddda7b 100644 --- a/pubsub/query/parser_test.go +++ b/pubsub/query/parser_test.go @@ -13,30 +13,37 @@ func TestParser(t *testing.T) { query string valid bool }{ - {"tm.events.type=NewBlock", true}, - {"tm.events.type = NewBlock", true}, - {"tm.events.type=TIME", true}, - {"tm.events.type=DATE", true}, + {"tm.events.type='NewBlock'", true}, + {"tm.events.type = 'NewBlock'", true}, + {"tm.events.name = ''", true}, + {"tm.events.type='TIME'", true}, + {"tm.events.type='DATE'", true}, + {"tm.events.type='='", true}, + {"tm.events.type='TIME", false}, + {"tm.events.type=TIME'", false}, {"tm.events.type==", false}, + {"tm.events.type=NewBlock", false}, {">==", false}, - {"tm.events.type NewBlock =", false}, - {"tm.events.type>NewBlock", false}, + {"tm.events.type 'NewBlock' =", false}, + {"tm.events.type>'NewBlock'", false}, {"", false}, {"=", false}, - {"=NewBlock", false}, + {"='NewBlock'", false}, {"tm.events.type=", false}, {"tm.events.typeNewBlock", false}, + {"tm.events.type'NewBlock'", false}, + {"'NewBlock'", false}, {"NewBlock", false}, {"", false}, - {"tm.events.type=NewBlock AND abci.account.name=Igor", true}, - {"tm.events.type=NewBlock AND", false}, - {"tm.events.type=NewBlock AN", false}, - {"tm.events.type=NewBlock AN tm.events.type=NewBlockHeader", false}, - {"AND tm.events.type=NewBlock ", false}, + {"tm.events.type='NewBlock' AND abci.account.name='Igor'", true}, + {"tm.events.type='NewBlock' AND", false}, + {"tm.events.type='NewBlock' AN", false}, + {"tm.events.type='NewBlock' AN tm.events.type='NewBlockHeader'", false}, + {"AND tm.events.type='NewBlock' ", false}, - {"abci.account.name CONTAINS Igor", true}, + {"abci.account.name CONTAINS 'Igor'", true}, {"tx.date > DATE 2013-05-03", true}, {"tx.date < DATE 2013-05-03", true}, @@ -68,6 +75,9 @@ func TestParser(t *testing.T) { {"account.balance >= -300", false}, {"account.balance >>= 400", false}, {"account.balance=33.22.1", false}, + + {"hash='136E18F7E4C348B780CF873A0BF43922E5BAFA63'", true}, + {"hash=136E18F7E4C348B780CF873A0BF43922E5BAFA63", false}, } for _, c := range cases { diff --git a/pubsub/query/query.go b/pubsub/query/query.go index f084a3f98..fdfb87d7a 100644 --- a/pubsub/query/query.go +++ b/pubsub/query/query.go @@ -94,9 +94,12 @@ func (q *Query) Matches(tags map[string]interface{}) bool { case rulecontains: op = opContains case rulevalue: + // strip single quotes from value (i.e. "'NewBlock'" -> "NewBlock") + valueWithoutSingleQuotes := buffer[begin+1 : end-1] + // see if the triplet (tag, operator, operand) matches any tag // "tx.gas", "=", "7", { "tx.gas": 7, "tx.ID": "4AE393495334" } - if !match(tag, op, reflect.ValueOf(buffer[begin:end]), tags) { + if !match(tag, op, reflect.ValueOf(valueWithoutSingleQuotes), tags) { return false } case rulenumber: diff --git a/pubsub/query/query.peg b/pubsub/query/query.peg index 9654289c4..739892e4f 100644 --- a/pubsub/query/query.peg +++ b/pubsub/query/query.peg @@ -13,8 +13,8 @@ condition <- tag ' '* (le ' '* (number / time / date) / contains ' '* value ) -tag <- < (![ \t\n\r\\()"=><] .)+ > -value <- < (![ \t\n\r\\()"=><] .)+ > +tag <- < (![ \t\n\r\\()"'=><] .)+ > +value <- < '\'' (!["'] .)* '\''> number <- < ('0' / [1-9] digit* ('.' digit*)?) > digit <- [0-9] diff --git a/pubsub/query/query.peg.go b/pubsub/query/query.peg.go index 5cd0a9e32..37ce75cd9 100644 --- a/pubsub/query/query.peg.go +++ b/pubsub/query/query.peg.go @@ -442,7 +442,7 @@ func (p *QueryParser) Init() { position, tokenIndex = position0, tokenIndex0 return false }, - /* 1 condition <- <(tag ' '* ((le ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / (ge ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / ((&('=') (equal ' '* (number / time / date / value))) | (&('>') (g ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('<') (l ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('C' | 'c') (contains ' '* value)))))> */ + /* 1 condition <- <(tag ' '* ((le ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / (ge ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / ((&('=') (equal ' '* ((&('\'') value) | (&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('>') (g ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('<') (l ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('C' | 'c') (contains ' '* value)))))> */ func() bool { position16, tokenIndex16 := position, tokenIndex { @@ -473,6 +473,12 @@ func (p *QueryParser) Init() { } position++ break + case '\'': + if buffer[position] != rune('\'') { + goto l22 + } + position++ + break case '"': if buffer[position] != rune('"') { goto l22 @@ -556,6 +562,12 @@ func (p *QueryParser) Init() { } position++ break + case '\'': + if buffer[position] != rune('\'') { + goto l24 + } + position++ + break case '"': if buffer[position] != rune('"') { goto l24 @@ -750,50 +762,50 @@ func (p *QueryParser) Init() { position, tokenIndex = position42, tokenIndex42 } { - position43, tokenIndex43 := position, tokenIndex - if !_rules[rulenumber]() { - goto l44 - } - goto l43 - l44: - position, tokenIndex = position43, tokenIndex43 - if !_rules[ruletime]() { - goto l45 - } - goto l43 - l45: - position, tokenIndex = position43, tokenIndex43 - if !_rules[ruledate]() { - goto l46 - } - goto l43 - l46: - position, tokenIndex = position43, tokenIndex43 - if !_rules[rulevalue]() { - goto l16 + switch buffer[position] { + case '\'': + if !_rules[rulevalue]() { + goto l16 + } + break + case 'D', 'd': + if !_rules[ruledate]() { + goto l16 + } + break + case 'T', 't': + if !_rules[ruletime]() { + goto l16 + } + break + default: + if !_rules[rulenumber]() { + goto l16 + } + break } } - l43: + break case '>': { - position47 := position + position44 := position if buffer[position] != rune('>') { goto l16 } position++ - add(ruleg, position47) + add(ruleg, position44) } - l48: + l45: { - position49, tokenIndex49 := position, tokenIndex + position46, tokenIndex46 := position, tokenIndex if buffer[position] != rune(' ') { - goto l49 + goto l46 } position++ - goto l48 - l49: - position, tokenIndex = position49, tokenIndex49 + goto l45 + l46: + position, tokenIndex = position46, tokenIndex46 } { switch buffer[position] { @@ -818,23 +830,23 @@ func (p *QueryParser) Init() { break case '<': { - position51 := position + position48 := position if buffer[position] != rune('<') { goto l16 } position++ - add(rulel, position51) + add(rulel, position48) } - l52: + l49: { - position53, tokenIndex53 := position, tokenIndex + position50, tokenIndex50 := position, tokenIndex if buffer[position] != rune(' ') { - goto l53 + goto l50 } position++ - goto l52 - l53: - position, tokenIndex = position53, tokenIndex53 + goto l49 + l50: + position, tokenIndex = position50, tokenIndex50 } { switch buffer[position] { @@ -859,139 +871,139 @@ func (p *QueryParser) Init() { break default: { - position55 := position + position52 := position { - position56, tokenIndex56 := position, tokenIndex + position53, tokenIndex53 := position, tokenIndex if buffer[position] != rune('c') { - goto l57 + goto l54 } position++ - goto l56 - l57: - position, tokenIndex = position56, tokenIndex56 + goto l53 + l54: + position, tokenIndex = position53, tokenIndex53 if buffer[position] != rune('C') { goto l16 } position++ } - l56: + l53: { - position58, tokenIndex58 := position, tokenIndex + position55, tokenIndex55 := position, tokenIndex if buffer[position] != rune('o') { - goto l59 + goto l56 } position++ - goto l58 - l59: - position, tokenIndex = position58, tokenIndex58 + goto l55 + l56: + position, tokenIndex = position55, tokenIndex55 if buffer[position] != rune('O') { goto l16 } position++ } - l58: + l55: { - position60, tokenIndex60 := position, tokenIndex + position57, tokenIndex57 := position, tokenIndex if buffer[position] != rune('n') { - goto l61 + goto l58 } position++ - goto l60 - l61: - position, tokenIndex = position60, tokenIndex60 + goto l57 + l58: + position, tokenIndex = position57, tokenIndex57 if buffer[position] != rune('N') { goto l16 } position++ } - l60: + l57: { - position62, tokenIndex62 := position, tokenIndex + position59, tokenIndex59 := position, tokenIndex if buffer[position] != rune('t') { - goto l63 + goto l60 } position++ - goto l62 - l63: - position, tokenIndex = position62, tokenIndex62 + goto l59 + l60: + position, tokenIndex = position59, tokenIndex59 if buffer[position] != rune('T') { goto l16 } position++ } - l62: + l59: { - position64, tokenIndex64 := position, tokenIndex + position61, tokenIndex61 := position, tokenIndex if buffer[position] != rune('a') { - goto l65 + goto l62 } position++ - goto l64 - l65: - position, tokenIndex = position64, tokenIndex64 + goto l61 + l62: + position, tokenIndex = position61, tokenIndex61 if buffer[position] != rune('A') { goto l16 } position++ } - l64: + l61: { - position66, tokenIndex66 := position, tokenIndex + position63, tokenIndex63 := position, tokenIndex if buffer[position] != rune('i') { - goto l67 + goto l64 } position++ - goto l66 - l67: - position, tokenIndex = position66, tokenIndex66 + goto l63 + l64: + position, tokenIndex = position63, tokenIndex63 if buffer[position] != rune('I') { goto l16 } position++ } - l66: + l63: { - position68, tokenIndex68 := position, tokenIndex + position65, tokenIndex65 := position, tokenIndex if buffer[position] != rune('n') { - goto l69 + goto l66 } position++ - goto l68 - l69: - position, tokenIndex = position68, tokenIndex68 + goto l65 + l66: + position, tokenIndex = position65, tokenIndex65 if buffer[position] != rune('N') { goto l16 } position++ } - l68: + l65: { - position70, tokenIndex70 := position, tokenIndex + position67, tokenIndex67 := position, tokenIndex if buffer[position] != rune('s') { - goto l71 + goto l68 } position++ - goto l70 - l71: - position, tokenIndex = position70, tokenIndex70 + goto l67 + l68: + position, tokenIndex = position67, tokenIndex67 if buffer[position] != rune('S') { goto l16 } position++ } - l70: - add(rulecontains, position55) + l67: + add(rulecontains, position52) } - l72: + l69: { - position73, tokenIndex73 := position, tokenIndex + position70, tokenIndex70 := position, tokenIndex if buffer[position] != rune(' ') { - goto l73 + goto l70 } position++ - goto l72 - l73: - position, tokenIndex = position73, tokenIndex73 + goto l69 + l70: + position, tokenIndex = position70, tokenIndex70 } if !_rules[rulevalue]() { goto l16 @@ -1009,629 +1021,501 @@ func (p *QueryParser) Init() { position, tokenIndex = position16, tokenIndex16 return false }, - /* 2 tag <- <<(!((&('<') '<') | (&('>') '>') | (&('=') '=') | (&('"') '"') | (&(')') ')') | (&('(') '(') | (&('\\') '\\') | (&('\r') '\r') | (&('\n') '\n') | (&('\t') '\t') | (&(' ') ' ')) .)+>> */ + /* 2 tag <- <<(!((&('<') '<') | (&('>') '>') | (&('=') '=') | (&('\'') '\'') | (&('"') '"') | (&(')') ')') | (&('(') '(') | (&('\\') '\\') | (&('\r') '\r') | (&('\n') '\n') | (&('\t') '\t') | (&(' ') ' ')) .)+>> */ nil, - /* 3 value <- <<(!((&('<') '<') | (&('>') '>') | (&('=') '=') | (&('"') '"') | (&(')') ')') | (&('(') '(') | (&('\\') '\\') | (&('\r') '\r') | (&('\n') '\n') | (&('\t') '\t') | (&(' ') ' ')) .)+>> */ + /* 3 value <- <<('\'' (!('"' / '\'') .)* '\'')>> */ func() bool { - position75, tokenIndex75 := position, tokenIndex + position72, tokenIndex72 := position, tokenIndex { - position76 := position + position73 := position { - position77 := position + position74 := position + if buffer[position] != rune('\'') { + goto l72 + } + position++ + l75: { - position80, tokenIndex80 := position, tokenIndex + position76, tokenIndex76 := position, tokenIndex { - switch buffer[position] { - case '<': - if buffer[position] != rune('<') { - goto l80 - } - position++ - break - case '>': - if buffer[position] != rune('>') { - goto l80 - } - position++ - break - case '=': - if buffer[position] != rune('=') { - goto l80 - } - position++ - break - case '"': + position77, tokenIndex77 := position, tokenIndex + { + position78, tokenIndex78 := position, tokenIndex if buffer[position] != rune('"') { - goto l80 - } - position++ - break - case ')': - if buffer[position] != rune(')') { - goto l80 - } - position++ - break - case '(': - if buffer[position] != rune('(') { - goto l80 - } - position++ - break - case '\\': - if buffer[position] != rune('\\') { - goto l80 - } - position++ - break - case '\r': - if buffer[position] != rune('\r') { - goto l80 + goto l79 } position++ - break - case '\n': - if buffer[position] != rune('\n') { - goto l80 + goto l78 + l79: + position, tokenIndex = position78, tokenIndex78 + if buffer[position] != rune('\'') { + goto l77 } position++ - break - case '\t': - if buffer[position] != rune('\t') { - goto l80 - } - position++ - break - default: - if buffer[position] != rune(' ') { - goto l80 - } - position++ - break } - } - - goto l75 - l80: - position, tokenIndex = position80, tokenIndex80 - } - if !matchDot() { - goto l75 - } - l78: - { - position79, tokenIndex79 := position, tokenIndex - { - position82, tokenIndex82 := position, tokenIndex - { - switch buffer[position] { - case '<': - if buffer[position] != rune('<') { - goto l82 - } - position++ - break - case '>': - if buffer[position] != rune('>') { - goto l82 - } - position++ - break - case '=': - if buffer[position] != rune('=') { - goto l82 - } - position++ - break - case '"': - if buffer[position] != rune('"') { - goto l82 - } - position++ - break - case ')': - if buffer[position] != rune(')') { - goto l82 - } - position++ - break - case '(': - if buffer[position] != rune('(') { - goto l82 - } - position++ - break - case '\\': - if buffer[position] != rune('\\') { - goto l82 - } - position++ - break - case '\r': - if buffer[position] != rune('\r') { - goto l82 - } - position++ - break - case '\n': - if buffer[position] != rune('\n') { - goto l82 - } - position++ - break - case '\t': - if buffer[position] != rune('\t') { - goto l82 - } - position++ - break - default: - if buffer[position] != rune(' ') { - goto l82 - } - position++ - break - } - } - - goto l79 - l82: - position, tokenIndex = position82, tokenIndex82 + l78: + goto l76 + l77: + position, tokenIndex = position77, tokenIndex77 } if !matchDot() { - goto l79 + goto l76 } - goto l78 - l79: - position, tokenIndex = position79, tokenIndex79 + goto l75 + l76: + position, tokenIndex = position76, tokenIndex76 } - add(rulePegText, position77) + if buffer[position] != rune('\'') { + goto l72 + } + position++ + add(rulePegText, position74) } - add(rulevalue, position76) + add(rulevalue, position73) } return true - l75: - position, tokenIndex = position75, tokenIndex75 + l72: + position, tokenIndex = position72, tokenIndex72 return false }, /* 4 number <- <<('0' / ([1-9] digit* ('.' digit*)?))>> */ func() bool { - position84, tokenIndex84 := position, tokenIndex + position80, tokenIndex80 := position, tokenIndex { - position85 := position + position81 := position { - position86 := position + position82 := position { - position87, tokenIndex87 := position, tokenIndex + position83, tokenIndex83 := position, tokenIndex if buffer[position] != rune('0') { - goto l88 + goto l84 } position++ - goto l87 - l88: - position, tokenIndex = position87, tokenIndex87 + goto l83 + l84: + position, tokenIndex = position83, tokenIndex83 if c := buffer[position]; c < rune('1') || c > rune('9') { - goto l84 + goto l80 } position++ - l89: + l85: { - position90, tokenIndex90 := position, tokenIndex + position86, tokenIndex86 := position, tokenIndex if !_rules[ruledigit]() { - goto l90 + goto l86 } - goto l89 - l90: - position, tokenIndex = position90, tokenIndex90 + goto l85 + l86: + position, tokenIndex = position86, tokenIndex86 } { - position91, tokenIndex91 := position, tokenIndex + position87, tokenIndex87 := position, tokenIndex if buffer[position] != rune('.') { - goto l91 + goto l87 } position++ - l93: + l89: { - position94, tokenIndex94 := position, tokenIndex + position90, tokenIndex90 := position, tokenIndex if !_rules[ruledigit]() { - goto l94 + goto l90 } - goto l93 - l94: - position, tokenIndex = position94, tokenIndex94 + goto l89 + l90: + position, tokenIndex = position90, tokenIndex90 } - goto l92 - l91: - position, tokenIndex = position91, tokenIndex91 + goto l88 + l87: + position, tokenIndex = position87, tokenIndex87 } - l92: + l88: } - l87: - add(rulePegText, position86) + l83: + add(rulePegText, position82) } - add(rulenumber, position85) + add(rulenumber, position81) } return true - l84: - position, tokenIndex = position84, tokenIndex84 + l80: + position, tokenIndex = position80, tokenIndex80 return false }, /* 5 digit <- <[0-9]> */ func() bool { - position95, tokenIndex95 := position, tokenIndex + position91, tokenIndex91 := position, tokenIndex { - position96 := position + position92 := position if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l95 + goto l91 } position++ - add(ruledigit, position96) + add(ruledigit, position92) } return true - l95: - position, tokenIndex = position95, tokenIndex95 + l91: + position, tokenIndex = position91, tokenIndex91 return false }, /* 6 time <- <(('t' / 'T') ('i' / 'I') ('m' / 'M') ('e' / 'E') ' ' <(year '-' month '-' day 'T' digit digit ':' digit digit ':' digit digit ((('-' / '+') digit digit ':' digit digit) / 'Z'))>)> */ func() bool { - position97, tokenIndex97 := position, tokenIndex + position93, tokenIndex93 := position, tokenIndex { - position98 := position + position94 := position { - position99, tokenIndex99 := position, tokenIndex + position95, tokenIndex95 := position, tokenIndex if buffer[position] != rune('t') { - goto l100 + goto l96 } position++ - goto l99 - l100: - position, tokenIndex = position99, tokenIndex99 + goto l95 + l96: + position, tokenIndex = position95, tokenIndex95 if buffer[position] != rune('T') { - goto l97 + goto l93 } position++ } - l99: + l95: { - position101, tokenIndex101 := position, tokenIndex + position97, tokenIndex97 := position, tokenIndex if buffer[position] != rune('i') { - goto l102 + goto l98 } position++ - goto l101 - l102: - position, tokenIndex = position101, tokenIndex101 + goto l97 + l98: + position, tokenIndex = position97, tokenIndex97 if buffer[position] != rune('I') { - goto l97 + goto l93 } position++ } - l101: + l97: { - position103, tokenIndex103 := position, tokenIndex + position99, tokenIndex99 := position, tokenIndex if buffer[position] != rune('m') { - goto l104 + goto l100 } position++ - goto l103 - l104: - position, tokenIndex = position103, tokenIndex103 + goto l99 + l100: + position, tokenIndex = position99, tokenIndex99 if buffer[position] != rune('M') { - goto l97 + goto l93 } position++ } - l103: + l99: { - position105, tokenIndex105 := position, tokenIndex + position101, tokenIndex101 := position, tokenIndex if buffer[position] != rune('e') { - goto l106 + goto l102 } position++ - goto l105 - l106: - position, tokenIndex = position105, tokenIndex105 + goto l101 + l102: + position, tokenIndex = position101, tokenIndex101 if buffer[position] != rune('E') { - goto l97 + goto l93 } position++ } - l105: + l101: if buffer[position] != rune(' ') { - goto l97 + goto l93 } position++ { - position107 := position + position103 := position if !_rules[ruleyear]() { - goto l97 + goto l93 } if buffer[position] != rune('-') { - goto l97 + goto l93 } position++ if !_rules[rulemonth]() { - goto l97 + goto l93 } if buffer[position] != rune('-') { - goto l97 + goto l93 } position++ if !_rules[ruleday]() { - goto l97 + goto l93 } if buffer[position] != rune('T') { - goto l97 + goto l93 } position++ if !_rules[ruledigit]() { - goto l97 + goto l93 } if !_rules[ruledigit]() { - goto l97 + goto l93 } if buffer[position] != rune(':') { - goto l97 + goto l93 } position++ if !_rules[ruledigit]() { - goto l97 + goto l93 } if !_rules[ruledigit]() { - goto l97 + goto l93 } if buffer[position] != rune(':') { - goto l97 + goto l93 } position++ if !_rules[ruledigit]() { - goto l97 + goto l93 } if !_rules[ruledigit]() { - goto l97 + goto l93 } { - position108, tokenIndex108 := position, tokenIndex + position104, tokenIndex104 := position, tokenIndex { - position110, tokenIndex110 := position, tokenIndex + position106, tokenIndex106 := position, tokenIndex if buffer[position] != rune('-') { - goto l111 + goto l107 } position++ - goto l110 - l111: - position, tokenIndex = position110, tokenIndex110 + goto l106 + l107: + position, tokenIndex = position106, tokenIndex106 if buffer[position] != rune('+') { - goto l109 + goto l105 } position++ } - l110: + l106: if !_rules[ruledigit]() { - goto l109 + goto l105 } if !_rules[ruledigit]() { - goto l109 + goto l105 } if buffer[position] != rune(':') { - goto l109 + goto l105 } position++ if !_rules[ruledigit]() { - goto l109 + goto l105 } if !_rules[ruledigit]() { - goto l109 + goto l105 } - goto l108 - l109: - position, tokenIndex = position108, tokenIndex108 + goto l104 + l105: + position, tokenIndex = position104, tokenIndex104 if buffer[position] != rune('Z') { - goto l97 + goto l93 } position++ } - l108: - add(rulePegText, position107) + l104: + add(rulePegText, position103) } - add(ruletime, position98) + add(ruletime, position94) } return true - l97: - position, tokenIndex = position97, tokenIndex97 + l93: + position, tokenIndex = position93, tokenIndex93 return false }, /* 7 date <- <(('d' / 'D') ('a' / 'A') ('t' / 'T') ('e' / 'E') ' ' <(year '-' month '-' day)>)> */ func() bool { - position112, tokenIndex112 := position, tokenIndex + position108, tokenIndex108 := position, tokenIndex { - position113 := position + position109 := position { - position114, tokenIndex114 := position, tokenIndex + position110, tokenIndex110 := position, tokenIndex if buffer[position] != rune('d') { - goto l115 + goto l111 } position++ - goto l114 - l115: - position, tokenIndex = position114, tokenIndex114 + goto l110 + l111: + position, tokenIndex = position110, tokenIndex110 if buffer[position] != rune('D') { - goto l112 + goto l108 } position++ } - l114: + l110: { - position116, tokenIndex116 := position, tokenIndex + position112, tokenIndex112 := position, tokenIndex if buffer[position] != rune('a') { - goto l117 + goto l113 } position++ - goto l116 - l117: - position, tokenIndex = position116, tokenIndex116 + goto l112 + l113: + position, tokenIndex = position112, tokenIndex112 if buffer[position] != rune('A') { - goto l112 + goto l108 } position++ } - l116: + l112: { - position118, tokenIndex118 := position, tokenIndex + position114, tokenIndex114 := position, tokenIndex if buffer[position] != rune('t') { - goto l119 + goto l115 } position++ - goto l118 - l119: - position, tokenIndex = position118, tokenIndex118 + goto l114 + l115: + position, tokenIndex = position114, tokenIndex114 if buffer[position] != rune('T') { - goto l112 + goto l108 } position++ } - l118: + l114: { - position120, tokenIndex120 := position, tokenIndex + position116, tokenIndex116 := position, tokenIndex if buffer[position] != rune('e') { - goto l121 + goto l117 } position++ - goto l120 - l121: - position, tokenIndex = position120, tokenIndex120 + goto l116 + l117: + position, tokenIndex = position116, tokenIndex116 if buffer[position] != rune('E') { - goto l112 + goto l108 } position++ } - l120: + l116: if buffer[position] != rune(' ') { - goto l112 + goto l108 } position++ { - position122 := position + position118 := position if !_rules[ruleyear]() { - goto l112 + goto l108 } if buffer[position] != rune('-') { - goto l112 + goto l108 } position++ if !_rules[rulemonth]() { - goto l112 + goto l108 } if buffer[position] != rune('-') { - goto l112 + goto l108 } position++ if !_rules[ruleday]() { - goto l112 + goto l108 } - add(rulePegText, position122) + add(rulePegText, position118) } - add(ruledate, position113) + add(ruledate, position109) } return true - l112: - position, tokenIndex = position112, tokenIndex112 + l108: + position, tokenIndex = position108, tokenIndex108 return false }, /* 8 year <- <(('1' / '2') digit digit digit)> */ func() bool { - position123, tokenIndex123 := position, tokenIndex + position119, tokenIndex119 := position, tokenIndex { - position124 := position + position120 := position { - position125, tokenIndex125 := position, tokenIndex + position121, tokenIndex121 := position, tokenIndex if buffer[position] != rune('1') { - goto l126 + goto l122 } position++ - goto l125 - l126: - position, tokenIndex = position125, tokenIndex125 + goto l121 + l122: + position, tokenIndex = position121, tokenIndex121 if buffer[position] != rune('2') { - goto l123 + goto l119 } position++ } - l125: + l121: if !_rules[ruledigit]() { - goto l123 + goto l119 } if !_rules[ruledigit]() { - goto l123 + goto l119 } if !_rules[ruledigit]() { - goto l123 + goto l119 } - add(ruleyear, position124) + add(ruleyear, position120) } return true - l123: - position, tokenIndex = position123, tokenIndex123 + l119: + position, tokenIndex = position119, tokenIndex119 return false }, /* 9 month <- <(('0' / '1') digit)> */ func() bool { - position127, tokenIndex127 := position, tokenIndex + position123, tokenIndex123 := position, tokenIndex { - position128 := position + position124 := position { - position129, tokenIndex129 := position, tokenIndex + position125, tokenIndex125 := position, tokenIndex if buffer[position] != rune('0') { - goto l130 + goto l126 } position++ - goto l129 - l130: - position, tokenIndex = position129, tokenIndex129 + goto l125 + l126: + position, tokenIndex = position125, tokenIndex125 if buffer[position] != rune('1') { - goto l127 + goto l123 } position++ } - l129: + l125: if !_rules[ruledigit]() { - goto l127 + goto l123 } - add(rulemonth, position128) + add(rulemonth, position124) } return true - l127: - position, tokenIndex = position127, tokenIndex127 + l123: + position, tokenIndex = position123, tokenIndex123 return false }, /* 10 day <- <(((&('3') '3') | (&('2') '2') | (&('1') '1') | (&('0') '0')) digit)> */ func() bool { - position131, tokenIndex131 := position, tokenIndex + position127, tokenIndex127 := position, tokenIndex { - position132 := position + position128 := position { switch buffer[position] { case '3': if buffer[position] != rune('3') { - goto l131 + goto l127 } position++ break case '2': if buffer[position] != rune('2') { - goto l131 + goto l127 } position++ break case '1': if buffer[position] != rune('1') { - goto l131 + goto l127 } position++ break default: if buffer[position] != rune('0') { - goto l131 + goto l127 } position++ break @@ -1639,13 +1523,13 @@ func (p *QueryParser) Init() { } if !_rules[ruledigit]() { - goto l131 + goto l127 } - add(ruleday, position132) + add(ruleday, position128) } return true - l131: - position, tokenIndex = position131, tokenIndex131 + l127: + position, tokenIndex = position127, tokenIndex127 return false }, /* 11 and <- <(('a' / 'A') ('n' / 'N') ('d' / 'D'))> */ diff --git a/pubsub/query/query_test.go b/pubsub/query/query_test.go index 75d02ee49..431ae1fef 100644 --- a/pubsub/query/query_test.go +++ b/pubsub/query/query_test.go @@ -22,7 +22,7 @@ func TestMatches(t *testing.T) { err bool matches bool }{ - {"tm.events.type=NewBlock", map[string]interface{}{"tm.events.type": "NewBlock"}, false, true}, + {"tm.events.type='NewBlock'", map[string]interface{}{"tm.events.type": "NewBlock"}, false, true}, {"tx.gas > 7", map[string]interface{}{"tx.gas": 8}, false, true}, {"tx.gas > 7 AND tx.gas < 9", map[string]interface{}{"tx.gas": 8}, false, true}, @@ -40,8 +40,8 @@ func TestMatches(t *testing.T) { {"tx.time >= TIME 2013-05-03T14:45:00Z", map[string]interface{}{"tx.time": time.Now()}, false, true}, {"tx.time = TIME 2013-05-03T14:45:00Z", map[string]interface{}{"tx.time": txTime}, false, false}, - {"abci.owner.name CONTAINS Igor", map[string]interface{}{"abci.owner.name": "Igor,Ivan"}, false, true}, - {"abci.owner.name CONTAINS Igor", map[string]interface{}{"abci.owner.name": "Pavel,Ivan"}, false, false}, + {"abci.owner.name CONTAINS 'Igor'", map[string]interface{}{"abci.owner.name": "Igor,Ivan"}, false, true}, + {"abci.owner.name CONTAINS 'Igor'", map[string]interface{}{"abci.owner.name": "Pavel,Ivan"}, false, false}, } for _, tc := range testCases { @@ -60,5 +60,5 @@ func TestMatches(t *testing.T) { func TestMustParse(t *testing.T) { assert.Panics(t, func() { query.MustParse("=") }) - assert.NotPanics(t, func() { query.MustParse("tm.events.type=NewBlock") }) + assert.NotPanics(t, func() { query.MustParse("tm.events.type='NewBlock'") }) }