Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not match properly on double equals == expression when field name has a dot in it #120

Open
tgnla opened this issue Oct 16, 2019 · 10 comments

Comments

@tgnla
Copy link

tgnla commented Oct 16, 2019

@Skarlso

Hello, thank you for this great gem!

I think this is a bug.

I took a crack at fixing this, but wasn't able to figure out exactly where I should intervene in the parsing process to make it work, so I'm bringing it up here.

See this failing test:
tgnla@c799448

Happy to provide more info upon request, and if you can point me in the right direction I may be able to get it working myself.

Thanks again.

@tgnla
Copy link
Author

tgnla commented Oct 16, 2019

To make it clearer:

I want to filter on json data that looks like this:

{
   "resources":[
      {
         "name":"igloo-1",
         "type":"Types.igloos",
         "foo":{
            "bar":"baz"
         }
      },
      {
         "name":"igloo-2",
         "type":"Types.igloos"
      },
      {
         "name":"brick-house-1",
         "type":"Types.brickHouses"
      }
   ]
}

I would expect a jsonpath string that looks like this:

$.resources[*][?(@['type'] == 'Types.igloos')].name

to find

[ {
     "name":"igloo-1",
     "type":"Types.igloos",
     "foo":{
        "bar":"baz"
     }
  },  {
     "name":"igloo-2",
     "type":"Types.igloos"
  }
]

but it finds

[]

@tgnla tgnla changed the title Does not match properly on == expression when field name has a dot in it Does not match properly on double equals == expression when field name has a dot in it Oct 16, 2019
@Skarlso
Copy link
Collaborator

Skarlso commented Oct 17, 2019

Hello! Thank you for reporting! :) I will check this out as soon as I can! :)

@Skarlso
Copy link
Collaborator

Skarlso commented Oct 17, 2019

Yeah, so dot is an identifier, so it splits it up by dot. Inconvenient. :D

@Skarlso
Copy link
Collaborator

Skarlso commented Oct 17, 2019

Okay, this is not going to be possible without messing up everything that's built around . being an identifier. What I can do is, make the regex a bit more strict in terms of if you don't want . to be handled as an identifier for a call, you have to escape it. Put two or one \ in front of the dot. Something like this:

$.resources[*][?(@['type'] == 'Types\\.igloos')].name

This way, jsonpath will know that . should not be handled as an identifier.

@Skarlso
Copy link
Collaborator

Skarlso commented Oct 17, 2019

It's actually harder than that, because the . makes it so that the identifier is not handled as a word, but two words. :/

@tgnla
Copy link
Author

tgnla commented Oct 17, 2019

Thanks for looking into this.

fwiw, it appears not all jsonpath implementations support this.

https://jsonpath.herokuapp.com/

Jayway does
image

Gatling does
image

Nebhale does not
image

Goessner does not
image

@Skarlso
Copy link
Collaborator

Skarlso commented Oct 17, 2019

Yeah there are some problems with doing this, but I'll figure something out! :))

@Skarlso
Copy link
Collaborator

Skarlso commented Oct 19, 2019

@tgnla Yo. So, as a workaround for now, until I figure something out... This actually works:

"$.resources[*][?(@.type == 'Types.igloos')].name"

Notice how I'm using @.type instead of @['type'].

@tgnla
Copy link
Author

tgnla commented Oct 19, 2019

Great! Thank you for that.

@rjofre
Copy link

rjofre commented Jan 31, 2023

Hello, first of all congratulations for this gem, it is extremely useful.

I have a question related to this issue, it is a very similar case. I am working on a query given the value of a datum. This value can be any text and specifically I have had problems when in this text there is a comma ,.

Example:

$.data[?(@.option == 'Hello, world')]

I checked this issue (#120) and I saw that even though it is open, the problem indicated with the . point is already solved. At least that's what it looks like when running the test with that case (provided above #120 (comment)):

def test_object_field_with_dot
  data = {
    'resources' => [
      { 'name' => 'igloo-1',
        'type' => 'Types.igloos', 'foo' => { 'bar' => 'baz'} },
      { 'name' => 'igloo-2',
        'type' => 'Types.igloos' },
      { 'name' => 'brick-house-1',
        'type' => 'Types.brickHouses' }
    ]
  }
  jp = JsonPath.new("$.resources[*][?(@['type'] == 'Types.igloos')].name")
  assert_equal(%w[igloo-1 igloo-2], jp.on(data))
end

Screenshot 2023-01-31 at 11 52 50

In my case, with the comma, I built a test based on the previous one and this is what I got as error:

def test_comma_in_value
    data = {
      'data' => [{
        'option' => 'Hi world',
        'case' => 'without_comma'
      }, {
        'option' => 'Hello, world',
        'case' => 'with_comma'
      }]
    }
    jp = JsonPath.new("$.data[?(@.option == 'Hello, world')].case")
    assert_equal(%w(with_comma), jp.on(data))
  end

Screenshot 2023-01-31 at 12 10 29

Checking the lines indicated in the backtrace, maybe my problem is related with this split (https://github.com/joshbuddy/jsonpath/blob/master/lib/jsonpath/enumerable.rb#L55):

[expr[1, expr.size - 2].split(',').each do |sub_path|]

Here we divide the expression, but since the value we ask for has a comma in it, it divides it incorrectly.

Anyway, I'm not 100% sure if the error exposed in this test is really a issue or if I'm doing something wrong in the query, so I would appreciate your feedback. And in case it really is a issue, I would appreciate any indication to see how to contribute to fix it.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants