Allow paren queries

This commit is contained in:
tidwall 2019-06-29 11:31:27 -07:00
parent f8322e865d
commit 6781e4ee59
2 changed files with 27 additions and 6 deletions

View File

@ -737,7 +737,13 @@ func parseArrayPath(path string) (r arrayPathResult) {
r.alogok = true r.alogok = true
r.alogkey = path[2:] r.alogkey = path[2:]
r.path = path[:1] r.path = path[:1]
} else if path[1] == '[' { } else if path[1] == '[' || path[1] == '(' {
var end byte
if path[1] == '[' {
end = ']'
} else {
end = ')'
}
r.query.on = true r.query.on = true
// query // query
i += 2 i += 2
@ -755,7 +761,7 @@ func parseArrayPath(path string) (r arrayPathResult) {
path[i] == '<' || path[i] == '<' ||
path[i] == '>' || path[i] == '>' ||
path[i] == '%' || path[i] == '%' ||
path[i] == ']' { path[i] == end {
break break
} }
} }
@ -817,7 +823,7 @@ func parseArrayPath(path string) (r arrayPathResult) {
break break
} }
} }
} else if path[i] == ']' { } else if path[i] == end {
if i+1 < len(path) && path[i+1] == '#' { if i+1 < len(path) && path[i+1] == '#' {
r.query.all = true r.query.all = true
} }
@ -1495,16 +1501,22 @@ func splitPossiblePipe(path string) (left, right string, ok bool) {
if i == len(path) { if i == len(path) {
return return
} }
if path[i] == '[' || path[i] == '(' {
var start, end byte
if path[i] == '[' { if path[i] == '[' {
start, end = '[', ']'
} else {
start, end = '(', ')'
}
// inside selector, balance brackets // inside selector, balance brackets
i++ i++
depth := 1 depth := 1
for ; i < len(path); i++ { for ; i < len(path); i++ {
if path[i] == '\\' { if path[i] == '\\' {
i++ i++
} else if path[i] == '[' { } else if path[i] == start {
depth++ depth++
} else if path[i] == ']' { } else if path[i] == end {
depth-- depth--
if depth == 0 { if depth == 0 {
break break

View File

@ -1853,3 +1853,12 @@ func TestQueryArrayValues(t *testing.T) {
assert(t, Get(json, `a*.#[_%"John*"]#|#`).String() == "0") assert(t, Get(json, `a*.#[_%"John*"]#|#`).String() == "0")
assert(t, Get(json, `a*.#[="123"]#|#`).String() == "1") assert(t, Get(json, `a*.#[="123"]#|#`).String() == "1")
} }
func TestParenQueries(t *testing.T) {
json := `{
"friends": [{"a":10},{"a":20},{"a":30},{"a":40}]
}`
assert(t, Get(json, "friends.#(a>9)#|#").Int() == 4)
assert(t, Get(json, "friends.#(a>10)#|#").Int() == 3)
assert(t, Get(json, "friends.#(a>40)#|#").Int() == 0)
}