go-jmespath icon indicating copy to clipboard operation
go-jmespath copied to clipboard

supporting Hyphen"-" in Compile and Search

Open b-entangled opened this issue 4 years ago • 5 comments

Hi, I tried the below code, where we want to search jmes path having Hyphen "-", I'm getting the following error SyntaxError: Unexpected token at the end of the expression: tNumber

From the code it looks like the Hyphen "-" is considered as a reference to get numeric values. https://github.com/jmespath/go-jmespath/blob/3d4fd11601ddca248480565884e34e393313cd62/lexer.go#L164-L166

package main

import (
	"encoding/json"
	"fmt"
	"github.com/jmespath/go-jmespath"
)

func main() {
	var jsondata = []byte(`{"foo-bar": {"bar": "car"}}`)
	var data interface{}
	err := json.Unmarshal(jsondata, &data)
	fmt.Println(err)
	precompiled, err := jmespath.Compile("foo-bar")
	if err != nil{
      	    fmt.Println(err)
   	}
    	result, err := precompiled.Search(data)
	fmt.Printf("%T", result)
	fmt.Println(result, err)
}

Is it possible to pass values containing Hyphen "-"? jmespath.Compile("foo-bar")

Please let us know if there is any other way to do that, If not please consider our suggestion. Opinion:-

Can we add a filter func in Lexer https://github.com/jmespath/go-jmespath/blob/3d4fd11601ddca248480565884e34e393313cd62/lexer.go#L23-L29

type SkipFilterFunc func(r rune) bool

// Lexer contains information about the expression being tokenized.
type Lexer struct {
	expression string       // The expression provided by the user.
	currentPos int          // The current position in the string.
	lastWidth  int          // The width of the current rune.  This
	buf        bytes.Buffer // Internal buffer used for building up values.
	skipFunc []SkipFilterFunc 
}

https://github.com/jmespath/go-jmespath/blob/3d4fd11601ddca248480565884e34e393313cd62/lexer.go#L388-L392 And we can call those filter func inside consuleUnquotedIdentifier

		if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 {
			skip := false
			for _, skipFunc := range lexer.skipFunc{
				if ok := skipFunc(r); ok {
					skip = true
					break
				}
			}
			if skip{
				continue
			}
			lexer.back()
			break

		}

So I can support any key to be part of string and can override the existing feature.

b-entangled avatar Sep 22 '20 08:09 b-entangled

If this is like the python library what may work is jmespath.Compile("\"foo-bar\"")

edit: yep https://play.golang.org/p/8SezRZLbyMR

nevins-b avatar Oct 06 '20 17:10 nevins-b

For anyone else stumbling on this issue the following worked for me:

role_attribute_path: contains("custom:groups"[*], 'Admin-Users') && 'Admin' || contains("custom:groups"[*], 'Grafana-Editor') && 'Editor' || 'Viewer'

weir-it-services avatar Oct 21 '20 14:10 weir-it-services

Is there an update on this? The workaround seems to work but doesn't seem ideal, especially for complex queries.

ghost avatar Apr 11 '21 21:04 ghost

Not being able to use field names with an - in a query is making problems quite often. Would be great to get it fixed.

Robert-M-Muench avatar Oct 25 '21 17:10 Robert-M-Muench

If this is like the python library what may work is jmespath.Compile("\"foo-bar\"") edit: yep https://play.golang.org/p/8SezRZLbyMR

Didn't recognize the answer... Yes, with escaping using hyphen in keys works.

Robert-M-Muench avatar Oct 25 '21 20:10 Robert-M-Muench